从大文件中读取 JSON 对象
本文关键字:JSON 对象 读取 文件 | 更新日期: 2023-09-27 18:30:43
我正在寻找一个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);
}
但它返回一个又一个令牌。
如果我需要整个对象而不是令牌,有没有更简单的方法?
假设你有一个类似于这样的 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();
}
}
我会 JSON.net 使用这个库。Nuget 的命令如下所示 -> Install-Package Newtonsoft.json
这是我为自己的解析器/反序列化器考虑的用例之一。
我最近做了一个简单的例子(通过向解析器提供通过 StreamReader 读取的 JSON 文本)来反序列化这个 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
(即具体:"父亲数据"、"父亲"、"儿子"、"女儿")
该示例还显示:
(1) 对 Father[] 数组中相对项目索引的示例过滤器(例如,仅获取前 10 个),以及
(2) 如何动态填充父亲女儿的属性,因为它们各自的父亲的反序列化返回 - (也就是说,感谢调用者传递给解析器的 Parse 方法的委托,用于回调目的)。
有关其余位,请参阅:
ParserTests.cs : static void FilteredFatherStreamTestDaughterMaidenNamesFixup()
(#829 至 #904 行)
我在不起眼的笔记本电脑 (*) 上观察到的性能,用于解析一些 ~ 12MB 到 ~ 180MB 的 JSON 文件并将其内容的任意子集反序列化为 POCO
(或进入松散类型的字典(仅支持(字符串、对象)键/值对)
在球场上从 ~ 20MB/秒到 40MB/秒 (**) 的任何位置。
(例如,在 12MB JSON 文件的情况下,~ 300 毫秒进入 POCO)
更详细的信息可在此处获得:
https://github.com/ysharplanguage/FastJsonParser#Performance
'嘿嘿,
(*) (运行 Win7 64 位 @ 2.5Ghz)
(**)(吞吐量很大程度上取决于输入的 JSON 形状/复杂性,例如子对象嵌套深度和其他因素)