首页 > 解决方案 > 在已排序的 5 GB 文件中快速搜索行

问题描述

我必须确定给定的行(作为字符串)是否存在于排序的文本文件中。该文件中的数据每天都在变化,平均有 1.52 亿条记录,文件大小约为 5GB。该文件按字母顺序排列,记录由新行分隔。

示例:搜索你好

文件:
苹果
香蕉
番茄酱

你好

我不需要搜索整个文件。一旦我找到了一个确切的名称,它就可以返回一个字符串或整数。只是为了证明它的存在。

我尝试了以下方法:

using (var sr = new StreamReader(txtFile))
{
   string line;
   while ((line = sr.ReadLine()) != null)
   {
       if (line == searchedWord)
           return true;
   }
   return false;
}
int result = File.ReadLines(txtFile).Count(line => line.Equals(searchedWord));
if (result > 0)
   return true;
return false;

我的问题是:有没有更好的解决方案来找到这条线?

标签: c#.netsearch.net-4.6

解决方案


我已经测试了这段代码:

private static bool ReadLineByLine(string path, string needle)
{
    using (var sr = new StreamReader(path))
    {
        string line;
        while ((line = sr.ReadLine()) != null)
        {
            if (line == needle)
                return true;
        }
        return false;
    }
}

它会在 12 秒内找到一个位于 5 GB 文件末尾的字符串。如果您的程序需要一整天的时间来执行此操作,我建议不要从 486 上的旋转磁盘读取,而是购买 50 美元的 SSD 和体面的 CPU 并在该硬件上处理文件。

您需要分析缓慢的来源,并且需要显示一些实际数字。您是否从网络共享中读取,您的程序需要多长时间?

您可以执行一些技巧来读取文件系统的理想大小的块中的文件,并行处理这些块(并考虑一个块可能包含针头的开始,而下一个块可能包含其余部分)等等,但要意识到,为了使框架的磁盘访问尽可能高效,我们做了很多工作。

不要智取框架,在体面的硬件上运行你的代码。


推荐阅读