如何在.NET中读取大(1 GB)的txt文件?
我有一个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); } } } }
在FormatData()
我检查必须与一个单词匹配的行的起始单词,并基于该单词的整数variables。
void FormatData(string line) { if (line.StartWith(word)) { globalIntVariable++; } }
如果您正在使用.NET 4.0,请尝试MemoryMappedFile ,这是此场景的devise类。
否则,您可以使用StreamReader.ReadLine
。
使用StreamReader可能是一种方法,因为您不希望将整个文件一次存储在内存中。 MemoryMappedFile比顺序读取更适合随机存取(对于顺序读取而言,快速十倍,对于随机存取而言,存储器映射快十倍)。
您也可以尝试使用FileOptions设置为SequentialScan(请参阅FileOptions Enumeration )从文件stream创buildstream式读取器 ,但是我怀疑这会产生很大的差别。
但是,有一些方法可以使你的例子更有效,因为你可以像阅读一样在循环中进行格式化。 你在浪费时钟,所以如果你想获得更多的性能,那么multithreadingasynchronous解决scheme会更好,一个线程读取数据,另一个线程在可用时将其格式化。 Checkout BlockingColletion可能适合您的需求:
阻止收集和生产者 – 消费者问题
如果你想获得最快的性能,按照我的经验,唯一的办法就是依次读入一大块二进制数据,并且将它反序列化为文本,但是代码在这一点上开始变得复杂起来。
你可以使用LINQ :
int result = File.ReadLines(filePath).Count(line => line.StartsWith(word));
File.ReadLines返回一个IEnumerable <String> ,它懒惰地从文件中读取每一行而不将整个文件加载到内存中。
Enumerable.Count统计以单词开头的行。
如果您从UI线程调用此函数,请使用BackgroundWorker 。
大概是逐行阅读。
你不应该试图通过阅读结束然后处理来强迫它进入记忆。
StreamReader.ReadLine
应该可以正常工作。 让框架select缓冲,除非你知道通过分析你可以做得更好。
TextReader.ReadLine()
我一次读取10000个字节的文件。 然后,我会分析这些10,000字节,并将它们切成行,并将它们送到FormatData函数。
在多个线程上分割阅读和线性分析的奖励点。
我肯定会使用一个StringBuilder来收集所有的string,并可能build立一个string缓冲区来保持大约100个string在内存中。
在Agenty的生产服务器上,我们遇到了同样的问题,在那里我们看到大文件(有时10-25 gb(\ t)制表符分隔的txt文件)。 经过大量的testing和研究后,我发现最好的方法是使用/ foreach循环读取小文件中的大文件,并使用File.ReadLines()设置偏移和限制逻辑。
int TotalRows = File.ReadLines(Path).Count(); // Count the number of rows in file with lazy load int Limit = 100000; // 100000 rows per batch for (int Offset = 0; Offset < TotalRows; Offset += Limit) { var table = Path.FileToTable(heading: true, delimiter: '\t', offset : Offset, limit: Limit); // Do all your processing here and with limit and offset and save to drive in append mode // The append mode will write the output in same file for each processed batch. table.TableToFile(@"C:\output.txt"); }
请参阅我的Github库中的完整代码: https : //github.com/Agenty/FileReader/
完全披露 – 我为Agenty(拥有该图书馆和网站的公司)工作