如何在.NET中读取大型(1 GB)txt文件?

Jee*_*att 55 c#

我有一个1 GB的文本文件,我需要逐行阅读.最好和最快的方法是什么?

private void ReadTxtFile()
{            
    string filePath = string.Empty;
    filePath = openFileDialog1.FileName;
    if (string.IsNullOrEmpty(filePath))
    {
        using (StreamReader sr = new StreamReader(filePath))
        {
            String line;
            while ((line = sr.ReadLine()) != null)
            {
                FormatData(line);                        
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

FormatData()我检查线必须以一个字相匹配,并基于该增量的整数变量的起始字.

void FormatData(string line)
{
    if (line.StartWith(word))
    {
        globalIntVariable++;
    }
}
Run Code Online (Sandbox Code Playgroud)

Tal*_*ner 48

如果您使用的是.NET 4.0,请尝试使用 MemoryMappedFile,它是此方案的设计类.

你可以使用StreamReader.ReadLine否则.

  • 如果你只是进行顺序读取,那么使用StreamReader比使用MemoryMappedFile更好,因为它更快.内存映射更适合随机访问. (44认同)
  • 此外,您可能无法创建跨越整个1 GB的ViewAccesor,因此您必须管理它以及解析换行符.FileStreams的速度是内存映射文件的10倍,用于顺序读取. (3认同)
  • @ konrad - 同意,评论很好,仅供参考.在O'Reilly的优秀"C#4.0 in a Nutshell"中,第569页对此进行了一些讨论.对于顺序I/O和1GB文件大小,那么MemoryMappedFiles肯定是矫枉过正并可能减慢速度. (3认同)

Hom*_*mde 31

使用StreamReader可能是一种方法,因为您不希望一次将整个文件放在内存中.MemoryMappedFile比随机读取更适合随机访问(顺序读取速度快10倍,内存映射速度是随机访问速度的十倍).

您也可以尝试从FileOptions设置为SequentialScan的文件流中创建您的streamreader(请参阅FileOptions枚举),但我怀疑它会产生很大的不同.

但是,有一些方法可以使您的示例更有效,因为您在与阅读相同的循环中进行格式化.你正在浪费时钟周期,所以如果你想要更高的性能,那么使用多线程异步解决方案会更好,其中一个线程读取数据而另一个线程在可用时对其进行格式化.Checkout BlockingColletion可能符合您的需求:

阻止收集和生产者 - 消费者问题

如果你想要尽可能快的性能,根据我的经验,唯一的方法是顺序读入一大块二进制数据并将其反序列化为文本并行,但代码在这一点上开始变得复杂.


dtb*_*dtb 15

您可以使用LINQ:

int result = File.ReadLines(filePath).Count(line => line.StartsWith(word));
Run Code Online (Sandbox Code Playgroud)

File.ReadLines返回一个IEnumerable <String>,懒惰地从文件中读取每一行而不将整个文件加载到内存中.

Enumerable.Count计算以单词开头的行.

如果从UI线程调用此方法,请使用BackgroundWorker.


Adr*_*der 10

可能要逐行阅读.

你还是不要试图通过读取结束,然后处理迫使它到内存中.


Mat*_*hen 8

StreamReader.ReadLine应该工作正常.让框架选择的缓冲,除非你知道通过剖析你可以做的更好.

  • @Jeevan你能定义"慢"吗?如果您在*n*时间内读取[小文件],则会在*n*[大文件]/[小文件]*中读取大文件.也许你正在经历预期的事情? (2认同)