.NET中如何从JSON文件逐个反序列化大对象以避免内存溢出?
内存安全的JSON大对象逐行反序列化方案
针对大JSON数组的反序列化场景,直接反序列化为List<T>会导致内存占用过高引发OutOfMemory异常,我们可以采用流式逐对象读取的方式,用JsonTextReader逐个解析数组中的元素,处理完一个对象再读取下一个,全程仅在内存中保留单个对象实例,实现内存安全。
核心实现思路
利用Newtonsoft.Json的JsonTextReader逐token遍历JSON内容:
- 跳过数组的起始(
StartArray)和结束(EndArray)标记 - 遇到每个对象的起始标记(
StartObject)时,将当前token反序列化为单个TPV对象 - 处理该对象(如存入数据库)后,继续读取下一个对象
完整反序列化代码
// 反序列化:流式逐对象处理 using (var fileStream = new FileStream(DirPath + "/TPV.Json", FileMode.Open)) using (var sr = new StreamReader(fileStream)) using (var jr = new JsonTextReader(sr)) { var serializer = new JsonSerializer(); // 跳过数组开始标记 while (jr.Read() && jr.TokenType != JsonToken.StartArray) { } // 遍历数组内的每个对象 while (jr.Read()) { if (jr.TokenType == JsonToken.EndArray) break; // 数组结束,退出循环 if (jr.TokenType == JsonToken.StartObject) { // 反序列化为单个TPV对象 var tpv = serializer.Deserialize<TPV>(jr); // 处理对象:存入数据库 using (var dbContext = new InspectionBatimentsDataContext(TheBrain.DBClient.ConnectionString)) { dbContext.TPV.InsertOnSubmit(tpv); dbContext.SubmitChanges(); } } } }
注意事项
- 确保使用与序列化一致的Newtonsoft.Json版本,避免兼容性问题
- 数据库操作可根据性能需求调整:比如积累N个对象后一次性提交,减少数据库连接开销
- 若JSON文件格式有缩进或换行,
JsonTextReader会自动处理,无需额外预处理
内容的提问来源于stack exchange,提问作者Julien Petitbon
相关产品推荐
相关产品推荐

