2012-08-22 75 views
2

我有一個大小爲50GB及以上的Json文件。 以下是我寫的閱讀Json的一小部分內容。我現在需要修改它來讀取大文件。在C#中高效地讀取極大文件。目前使用StreamReader

internal static IEnumerable<T> ReadJson<T>(string filePath) 
{ 
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); 
    using (StreamReader sr = new StreamReader(filePath)) 
    { 
     String line; 
     // Read and display lines from the file until the end of 
     // the file is reached. 
     while ((line = sr.ReadLine()) != null) 
     { 
      byte[] jsonBytes = Encoding.UTF8.GetBytes(line); 
      XmlDictionaryReader jsonReader = JsonReaderWriterFactory.CreateJsonReader(jsonBytes, XmlDictionaryReaderQuotas.Max); 
      var myPerson = ser.ReadObject(jsonReader); 
      jsonReader.Close(); 

      yield return (T)myPerson; 
     } 
    } 
} 
  1. 想如果我指定緩衝區大小,而在當前代碼構建的StreamReader就足夠了?
  2. 如果我在這裏錯了,請糾正我。緩衝區大小基本上指定了一次從磁盤讀取多少數據到內存。因此,如果文件大小爲100MB,緩衝區大小爲5MB,則每次讀取內存5MB,直到讀取完整個文件。
  3. 假設我對第3點的理解是正確的,那麼對於如此大的文本文件,理想的緩衝區大小是多少? int.Max大小是一個壞主意?在64位PC中,int.Max大小爲2147483647.我認爲緩衝區大小是以字節爲單位的,估計大約爲2GB。這本身可能會浪費時間。我一直在尋找像100MB - 300MB這樣的緩衝區大小。
+0

增加緩衝區的大小,甚至低至128K不太可能有很多好處。 1MB緩衝區已經比它需要的大。然而,確保唯一的方法是使用不同的緩衝區大小。 –

+0

50GB文件?如果是信用卡一覽表可我有一個副本,請(JK) –

回答

5

它將一次(輸入文件的)讀取一行,可能是10個字節,可能全部是50GB。所以歸結爲:輸入文件結構如何?如果輸入的JSON在對象之間的中斷處有換行其他,則這可能會變得非常糟糕。

緩衝區大小可能會影響其讀取的數量,同時在每行的末尾顯示,但最終:每次都需要找到一條新行(至少是如何寫入當前行)。

+0

文件結構如下 {} {} {} 基本上用大括號每個數據錄入 - {},然後一之後輸入密鑰。 正如我從你寫的東西瞭解到的,這是不是很有效,因爲它從文件中讀取每個數據項。我希望它讀取文件的部分內存,然後從那裏讀取每一行。我如何修改這個? –

+0

@ ShaQ.Blogs很好,每行有多長? (我假設每個''等都是一條線)。我真的不認爲這是一個問題。這聽起來像是你正在追求一個並非實際存在的性能問題,或者不是你認爲的問題 –

+0

每行大約1KB。 是的,那就對了。我假設我的代碼不會非常高效。我認爲將文件塊讀入內存然後讀取它會更高效。 –

0

我想你應該首先比較不同的解析器,然後再擔心細節作爲緩衝區大小。
DataContractJsonSerializer,Raven JSONNewtonsoft JSON之間的差異將非常顯着。

0

所以你的主要問題是你的界限在哪裏,並且鑑於你的文檔是JSON文檔,在我看來,你的界限很可能是類,我假設(或希望)沒有一個重要的50GB的大班。我也假設你並不真的需要所有這些內存類,但是你可能需要爲你的子集搜索整個事物......這聽起來大致正確嗎?如果是這樣,我認爲你的僞代碼是類似的

using a Json parser that accepts a streamreader (newtonsoft?) 
read and parse until eof 
    yield return your parsed class that matches criteria 
    read and parse next class 
end 
+0

我的算法基本上是, 1.從磁盤文件讀取數據項。 2.寫入數據到數據庫。 3.將數據錄入索引存儲在散列表中。 –

+0

@ ShaQ.Blogs酷,非常類似於上面那麼。所以我認爲這就是你需要的東西,只需使用一個JSON解析器,它將從一個流中解析並隨時寫入數據庫。 NewtonSoft.Json或Raven.Json是你最好的投注。 –

相關問題