C#在超过300万行的txt文件中搜索

Saj*_*are -1 c# out-of-memory memory-efficient

我有几个txt文件,每个文件包含超过300万行。每行包含客户的连接,其中有客户 ID、IP 地址......

我需要找到特定的 IP 地址并获取与其相关的客户 ID。

我读取该文件并将其拆分为一个数组,并通过 foreach 在每一行中进行搜索,但由于有很多行,因此出现以下错误。

引发了“System.OutOfMemoryException”类型的异常。

我应该解压缩 txt 文件,因为它们是压缩的。我使用下面的代码:

string decompressTxt = decompressTxt = this.Decompress(new FileInfo(filePath));
char[] delRow = { '\n' };
string[] rows = decompressTxt.Split(delRow);
for (int i = 0; i < rows.Length; i++){
   if(rows[i].Contains(ip)){
    
   }
}

string Decompress(FileInfo fileToDecompress)
{
   string newFileName = "";
   string newFIleText = "";
   using (FileStream originalFileStream =fileToDecompress.OpenRead())
   {
        string currentFileName = fileToDecompress.FullName;
        newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length);
    
        using (FileStream decompressedFileStream = File.Create(newFileName))
        {
               using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
               {             
                  decompressionStream.CopyTo(decompressedFileStream);
               }
         }
    
         newFIleText = File.ReadAllText(newFileName);
         File.Delete(newFileName);
    }
    return newFIleText;
}
Run Code Online (Sandbox Code Playgroud)

Eti*_*tel 5

好吧,即使在我们了解内存不足的原因之前,您正在做的很多事情都是不必要的。

\n

首先,解压不需要中间文件,直接读取GZipStream\xc2\xa0即可。但是等等,您是否认为您必须用来File.ReadAllText读取文本,因此这就是您首先解压缩文件的原因?

\n

那是没有必要的。当您想从流中读取文本时,只需使用 a 即可StreamReader(这就是File.ReadAllText下面的用法)。

\n

该阅读器还可以用于逐行读取,而无需将整个文件放入内存中,只需每次一行读取每一行。只要打电话ReadLine()直到它返回null

\n

将所有内容放在一起,下面的代码可以解压缩数据并一次读取一行,而无需拆分任何内容。它不仅可以扩展非常大的文件,而且速度也更快。

\n
using var stream = new GZipStream(fileToDecompress.OpenRead(), CompressionMode.Decompress);\nusing var reader = new StreamReader(stream);\n\nstring? line;\nwhile ((line = reader.ReadLine()) != null)\n{\n     if (line.Contains(ip))\n     {\n         // etc.\n     }\n}\n
Run Code Online (Sandbox Code Playgroud)\n