2011-06-24 122 views
5

我有4GB +文本文件(csv格式),我想在c#中使用linq處理此文件。在C中處理大文本文件#

我加載csv後運行復雜的linq查詢並轉換爲類?

但文件大小是4GB,但應用程序內存的文件大小是雙倍大小。

我該如何處理(linq和新結果)大文件?

感謝

+0

什麼五:可能

from record in GetRecords("myFile.csv",new []{"Foo","Bar"},new[]{","}) where record.Foo == "Baz" select new {MyRealBar = int.Parse(record.Bar) 

項目的CSV到克萊對象序列的方法可以像創建.NET的使用 –

+0

@Rune FS我正在使用.net 4.0 – oguzh4n

回答

11

不必加載整個文件到內存中,你可以讀取和處理文件中的行由行。

using (var streamReader = new StreamReader(fileName)) 
{ 
    string line; 
    while ((line = streamReader.ReadLine()) != null) 
    { 
     // analize line here 
     // throw it away if it does not match 
    } 
} 

[編輯]

如果你需要運行對文件中的數據進行復雜的查詢,做正確的事情是將數據加載到數據庫,並讓DBMS照顧數據檢索和內存管理。

+1

如果所有文本如果在沒有回車的單行中,那麼怎麼辦? – Burimi

+1

@Cody - 我認爲csv文件不是單行文件。 –

+2

然後,您將整行處理爲字節流,而不是一行行。 –

1

我覺得這是一個很好的方式... CSV

+0

[鏈接](http://i51.tinypic.com/5dphtg.png)問題是這樣的 讀字節500MB但內存2GB – oguzh4n

1

如果您使用的是.NET 4.0中,您可以使用Clay,然後寫一個返回行一個IEnumerable線的方法,這讓這樣的代碼下面

private IEnumerable<dynamic> GetRecords(
        string filePath, 
        IEnumerable<string> columnNames, 
        string[] delimiter){ 
      if (!File.Exists(filePath)) 
       yield break; 
      var columns = columnNames.ToArray(); 
      dynamic New = new ClayFactory(); 
      using (var streamReader = new StreamReader(filePath)){ 
       var columnLength = columns.Length; 
       string line; 
       while ((line = streamReader.ReadLine()) != null){ 
        var record = New.Record(); 
        var fields = line.Split(delimiter, StringSplitOptions.None); 
        if(fields.Length != columnLength) 
         throw new InvalidOperationException(
           "fields count does not match column count"); 
        for(int i = 0;i<columnLength;i++){ 
         record[columns[i]] = fields[i]; 
        } 
        yield return record; 
       } 
      } 
     } 
+0

感謝您的建議, 我試過這個解決方案,但它非常慢,並具有相同的內存問題。 – oguzh4n

+0

@ oguzh4n哦,我特意沒有考慮到速度,因爲你沒有在你的帖子中提到過。我希望可讀性(在這種情況下的呼叫網站)可以在任何一天超速。關於內存問題。如果你可以更精確地說明他們可以修復的問題。這並不需要一次保存多於一行的文本文件和一個粘土對象(以及一點點),所以上面的草稿有哪些內存問題,可以修復它們 –