2

我正在寻找一个 JSON 解析器,它可以让我从一个大型 JSON 文件(大小为几百 MB)中遍历 JSON 对象。我尝试了来自Json.NET的 JsonTextReader,如下所示:

JsonTextReader reader = new JsonTextReader(new StringReader(json));
while (reader.Read())
{
    if (reader.Value != null)
       Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value);
    else
       Console.WriteLine("Token: {0}", reader.TokenType);
}

但它在令牌后返回令牌。
如果我需要整个对象而不是令牌,有没有更简单的方法?

4

3 回答 3

2

假设您有一个类似于此的 json 数组:

[{"text":"0"},{"text":"1"}......]

我将为对象类型声明一个类

public class TempClass
{
    public string text;
}

现在,反序列化部分

JsonSerializer ser = new JsonSerializer();
ser.Converters.Add(new DummyConverter<TempClass>(t =>
    {
       //A callback method
        Console.WriteLine(t.text);
    }));

ser.Deserialize(new JsonTextReader(new StreamReader(File.OpenRead(fName))), 
                typeof(List<TempClass>));

和一个虚拟的 JsonConverter 类来拦截反序列化

public class DummyConverter<T> : JsonConverter
{
    Action<T> _action = null;
    public DummyConverter(Action<T> action)
    {
        _action = action;
    }
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(TempClass);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        serializer.Converters.Remove(this);
        T item = serializer.Deserialize<T>(reader);
        _action( item);
        return null;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
于 2013-09-10T14:34:37.913 回答
1

我会使用这个库JSON.net。Nuget 的命令如下 -> Install-Package Newtonsoft.Json

于 2013-09-10T09:23:08.893 回答
1

这是我为自己的解析器/反序列化器考虑的用例之一。

我最近做了一个反序列化这个 JSON 形状的简单示例(通过向解析器提供通过 StreamReader 读取的 JSON 文本):

{ 
"fathers" : [ 
{ 
  "id" : 0,
  "married" : true,
  "name" : "John Lee",
  "sons" : [ 
    { 
      "age" : 15,
      "name" : "Ronald"
      }
    ],
  "daughters" : [ 
    { 
      "age" : 7,
      "name" : "Amy"
      },
    { 
      "age" : 29,
      "name" : "Carol"
      },
    { 
      "age" : 14,
      "name" : "Barbara"
      }
    ]
  },
{ 
  "id" : 1,
  "married" : false,
  "name" : "Kenneth Gonzalez",
  "sons" : [
    ],
  "daughters" : [
    ]
  },
{ 
  "id" : 2,
  "married" : false,
  "name" : "Larry Lee",
  "sons" : [ 
    { 
      "age" : 4,
      "name" : "Anthony"
      },
    { 
      "age" : 2,
      "name" : "Donald"
      }
    ],
  "daughters" : [ 
    { 
      "age" : 7,
      "name" : "Elizabeth"
      },
    { 
      "age" : 15,
      "name" : "Betty"
      }
    ]
  },

  //(... etc)
  ]
}

...进入这些 POCO:

https://github.com/ysharplanguage/FastJsonParser#POCOs

(即,具体而言:“FathersData”、“Father”、“Son”、“Daughter”)

该示例还显示:

(1) 在 Father[] 数组中的相对项索引上的示例过滤器(例如,仅获取前 10 个),以及

(2) 如何动态填充父亲女儿的属性,因为他们各自的父亲的反序列化返回 - (也就是说,由于调用者传递给解析器的 Parse 方法的委托,用于回调目的)。

有关其余位,请参见:

ParserTests.cs : 静态无效 FilteredFatherStreamTestDaughterMaidenNamesFixup()

(第#829#904行)

我在我不起眼的笔记本电脑 (*) 上观察到的性能,用于解析大约 12MB 到 180MB 的 JSON 文件并将其内容的任意子集反序列化为 POCO

(或松散类型的字典(仅(字符串,对象)键/值对)也支持)

在大约 20MB/秒到 40MB/秒 (**) 的任何地方。

(例如,在 12MB JSON 文件的情况下,大约 300 毫秒进入 POCO)

此处提供更多详细信息:

https://github.com/ysharplanguage/FastJsonParser#Performance

'HTH,

(*) (运行 Win7 64bit @ 2.5Ghz)

(**)(吞吐量很大程度上取决于输入 JSON 的形状/复杂性,例如,子对象嵌套深度和其他因素)

于 2014-05-19T06:58:36.663 回答