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

C# 在非常大的文件C的所有行上循环#,c#,foreach,C#,Foreach,我想使用foreach 我目前使用的是File.ReadLines,如下所示: var lines = File.ReadLines(fileName); foreach (var line in lines) { // Process line } 但是,如果文件大于2MB,这是非常慢的,并且循环速度非常慢 如何在非常大的文件上循环 任何帮助都将不胜感激 谢谢 考虑到这一点,你这样做是最好的方式 您不想一次将整个文件读入RAM 您的行处理独立于以前的行 对不起,从硬盘上读东西太慢了

我想使用
foreach

我目前使用的是
File.ReadLines
,如下所示:

var lines = File.ReadLines(fileName);
foreach (var line in lines) {
  // Process line
}
但是,如果文件大于2MB,这是非常慢的,并且循环速度非常慢

如何在非常大的文件上循环

任何帮助都将不胜感激


谢谢

考虑到这一点,你这样做是最好的方式

  • 您不想一次将整个文件读入RAM
  • 您的行处理独立于以前的行
对不起,从硬盘上读东西太慢了

改进可能来自其他方面:

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

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

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

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

内存映射文件将为程序提供一个从内存访问的视图,但它将仅第一次从磁盘加载

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
     }
}

循环总是很慢的,因为你要循环的项目太多了。我很确定这不是循环,而是你在每一条线上所做的实际工作使它变慢了。一个有10GB行的文件实际上可能有数万亿行,除了最简单的任务外,任何事情都需要花费大量时间

您可以尝试使作业线程化,以便不同的线程在不同的线路上工作。这样至少你有更多的核心在解决这个问题

建立一个for循环,让它们以不同的数量递增

另外,我不是100%,但我认为你可以通过基于新行拆分整个字符串数组,然后处理这些字符串,从而大大提高速度,因为所有内容都存储在内存中

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

}
**根据评论添加** 因此存在巨大的负面影响,并将占用大量内存。至少是原始文件的使用量,但这解决了硬盘速度慢的问题,所有数据都将直接读取到机器的RAM中,这将远远快于从硬盘读取小块数据


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

为什么您认为OP只需要文件的一部分?我打赌OP正在逐行读取和处理:\n您的编辑忽略了
文件的事实。ReadLines
为您执行所有这些流式处理。我仍然认为这种方法甚至可以更好地加载到整个文件文件到内存,因为您可以控制流程并在需要时适当地显示消息。我看不出这是如何适用于该问题的。当然你可以这么做。。。在这上面写很多代码,甚至达到OP所看到的给定值。。。而且这还不是速度的提升所以。。。手动将10GB的数据复制到代码中,生成10GB内存中字符串文字?听起来很有趣…你猜呢?因为我认为你根本没有测试过这个。它不仅可能会变慢,还会浪费大约20GB或更多的RAM。“一个10GB行的文件实际上会有数万亿行…”->粘贴到阵列。现在我们有了一个10gb字符串文字(编译器将如何处理它(我很好奇))现在我们有了一个包含10gb值的条目的数组(我也很好奇它将如何处理)。这里的注释是:“你在猜吗?因为我认为你根本没有测试过这个”。当然我还没有测试过这个。我没有得到报酬。这些只是我的想法。OP可以到处玩,看看什么是FASTEST我同意,从RAM读取比从HDD读取“快得多”,但您的解决方案需要以慢速HDD的速度从慢速HDD读取到快速RAM。这和我从硬盘上逐行读取文件不一样吗?可能是重复的