在非常大的文件C#的所有行上循环

时间:2018-08-15 09:40:13

标签: c# foreach

我想使用foreach遍历一个非常大的文件(例如10GB)的所有行

我目前正在这样使用File.ReadLines

var lines = File.ReadLines(fileName);
foreach (var line in lines) {
  // Process line
}

但是如果文件大于2MB,这将非常慢,并且循环将非常慢。

如何循环播放非常大的文件?

任何帮助将不胜感激。

谢谢!

3 个答案:

答案 0 :(得分:1)

鉴于此,

  • 您不想一次将整个文件读入RAM
  • 您的行处理独立于先前的行

对不起,从硬盘读取内容很慢。

改进可能来自其他来源:

  • 将文件存储在更快的设备上(SSD?)
  • 获得更多RAM来将文件读入内存,至少可以加快处理速度

答案 1 :(得分:0)

首先,您需要读取整个文件或仅读取文件的一部分。

如果您只需要阅读文件的部分

const int chunkSize = 1024; // read the file by chunks of 1KB
using (var file = File.OpenRead("yourfile"))
{
    int bytesRead;
    var buffer = new byte[chunkSize];
    while ((bytesRead = file.Read(buffer, 0 /* start offset */, buffer.Length)) > 0)
    {
        // TODO: Process bytesRead number of bytes from the buffer
        // not the entire buffer as the size of the buffer is 1KB
        // whereas the actual number of bytes that are read are 
        // stored in the bytesRead integer.
    }
}

如果您需要将整个文件加载到内存中。

重复使用此方法,而不是直接将其加载到内存中,因为您可以控制自己的操作,并且随时可以停止该过程。

或者您可以使用 MemoryMappedFile https://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile.aspx?f=255&MSPPError=-2147217396

通过内存映射的文件可以从内存中访问程序,从而可以查看程序,但仅是第一次从磁盘加载。

long offset = 0x10000000; // 256 megabytes
long length = 0x20000000; // 512 megabytes

// Create the memory-mapped file.
using (var mmf = MemoryMappedFile.CreateFromFile(@"c:\ExtremelyLargeImage.data", FileMode.Open,"ImgA"))
{
     // Create a random access view, from the 256th megabyte (the offset)
     // to the 768th megabyte (the offset plus length).
     using (var accessor = mmf.CreateViewAccessor(offset, length))
     {
         //Your process
     }
}

答案 2 :(得分:-5)

由于您要循环通过的项目太多,因此循环总是很慢。我非常确定,不是循环,而是您在每一行上所做的实际工作会使速度变慢。具有10GB行的文件实际上可以包含数万亿行,但最简单的任务将需要大量时间。

您始终可以尝试使该作业成为线程,以便其他线程在不同的行上工作。这样,至少您可以有更多的核心来解决这个问题。

设置一个for循环,并使它们以不同的量递增。

另外,不是100%,但是我认为通过将新行基于新行进行拆分,然后将所有内容存储在内存中,您可以通过将整个事物拆分为字符串数组来提高速度。

string lines = "your huge text";
string[] words = lines.Split('\n');
foreach(string singleLine in lines)
{

}

**根据评论添加** 因此存在很大的缺点,并且会占用大量内存。至少要使用原始文件的数量,但是可以解决硬盘驱动器速度慢的问题,并且所有数据都将直接读取到计算机的RAM中,这比从小块中读取硬盘驱动器要快得多

这里还有一个问题,就是要限制大约20亿行,因为那是数组中可以拥有的最大条目数。