2

我有一个大小为 50GB 及以上的 Json 文件。以下是我为阅读一小部分 Json 所写的内容。我现在需要修改它来读取大文件。

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 size 会是个坏主意吗?在 64 位 PC 中,int.Max 大小为 2147483647。我假设缓冲区大小以字节为单位,计算结果约为 2GB。这本身可能会消耗时间。我正在寻找像 100MB - 300MB 这样的缓冲区大小。
4

3 回答 3

5

它将一次读取一行(输入文件),可能是 10 个字节,也可能是全部 50GB。所以归结为:输入文件的结构如何?如果输入 JSON 在对象之间的中断处有换行符那么这可能会变得很糟糕。

缓冲区大小可能会影响它在查找每行末尾时的读取量,但最终:它需要每次都找到一个换行符(至少,它当前是如何写入的)。

于 2012-08-22T08:18:48.753 回答
0

我认为您应该先比较不同的解析器,然后再担心缓冲区大小的细节。DataContractJsonSerializer、 Raven JSONNewtonsoft JSON
之间的差异将非常显着。

于 2012-08-22T08:34:26.877 回答
0

因此,您的主要问题是您的界限在哪里,并且鉴于您的文档是 JSON 文档,在我看来,您的界限很可能是类,我假设(或希望)您没有 1 个大喇叭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
于 2012-08-22T08:38:40.017 回答