2010-11-25 75 views
53

我有一個1 GB的文本文件,我需要逐行閱讀。什麼是最好和最快的方式來做到這一點?如何在.NET中讀取大(1 GB)的txt文件?

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()我檢查線的起始字必須以一個字相匹配,並基於該增量的整數變量。

void FormatData(string line) 
{ 
    if (line.StartWith(word)) 
    { 
     globalIntVariable++; 
    } 
} 
+0

您可能要張貼`FormatData`公司工作(或以防萬一。 – 2010-11-25 05:19:10

+0

@Matthew:只是忽略FormatData(),實際上整個過程很慢,所以對於我已經評論過的故障排除。 – 2010-11-25 05:22:58

+0

如果你想要一個快速的解決方案,你不能忽略`FormatData`,你最好在與讀取數據的單獨線程中格式化數據。 – cspolton 2010-11-25 07:09:36

回答

40

如果您使用的是.NET 4.0,嘗試MemoryMappedFile這是該方案設計的類。

可以使用StreamReader.ReadLine否則。

6

StreamReader.ReadLine應該正常工作。讓框架選擇緩衝,除非通過分析知道你可以做得更好。

28

使用的StreamReader大概是這樣以來你不希望在內存中的整個文件一次。 MemoryMappedFile比順序讀取更適合隨機存取(對於順序讀取而言,它的速度是十倍,存儲器映射的速度是隨機存取速度的十倍)。

您也可以嘗試從FILESTREAM設置爲SequentialScan FileOptions創建您的StreamReader(見FileOptions Enumeration),但我懷疑它將使太大的差別。

但是也有辦法讓你的例子更有效,因爲你做你的格式在同一迴路的讀數。你在浪費時鐘,所以如果你想獲得更多的性能,那麼多線程異步解決方案會更好,一個線程讀取數據,另一個線程將其格式化爲可用的格式。結帳BlockingColletion可能適合您的需要:

Blocking Collection and the Producer-Consumer Problem

如果你想在最快的性能,在我的經驗,唯一的方法是閱讀大數據依次二進制的塊,並將其反序列化爲文本並行,但代碼在這一點開始變得複雜。

0

我一次讀取10,000個字節的文件。然後,我會分析這些10,000字節並將它們分成幾行並將它們傳送給FormatData函數。

積分爲多個線程分裂閱讀和線analysation。

,我肯定會用一個StringBuilder收集所有字符串,並可能建立一個字符串緩衝區,以保持約100個字符串內存中的所有時間。

1

我在我們的生產服務器Agenty上遇到了同樣的問題,我們在這裏看到大文件(有時候是10-25 gb(\ t)製表符分隔的txt文件)。經過大量測試和研究後,我發現最好的方法是用/ 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,誰擁有這個庫和網站