2012-08-22 41 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是你最好的投注。 –

相关问题