使用NewtonSoft反序列化5-8GB大型JSON文件时对象为空问题
解决大JSON流式反序列化空对象问题
1. 先修复实体类的核心问题
(1)清理重复的Department定义
如果项目里存在多个同名Department类(比如不同命名空间下的重复定义),Json.NET会无法正确匹配目标类型,直接删除冗余定义,确保整个项目只有唯一的Department实体类。
(2)修正属性名称不匹配问题
Json.NET默认严格按属性名大小写匹配,两种解决方式:
- 给实体类属性添加
[JsonProperty]特性,绑定JSON中的对应键名:// 假设JSON里的键是"deptName",实体类属性是DepartmentName [JsonProperty("deptName")] public string DepartmentName { get; set; } - 配置序列化器忽略大小写,同时忽略JSON中存在但实体类没有的字段:
var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), MissingMemberHandling = MissingMemberHandling.Ignore };
2. 修正流式反序列化代码
确保用JsonSerializer结合StreamReader的写法正确,不要误用会加载整个文件到内存的JsonConvert.DeserializeObject。正确示例:
using (var stream = new FileStream(@"D:\large_company.json", FileMode.Open, FileAccess.Read)) using (var reader = new StreamReader(stream)) using (var jsonReader = new JsonTextReader(reader)) { var serializer = JsonSerializer.CreateDefault(settings); // 传入上面配置好的settings var company = serializer.Deserialize<CompanyDetails>(jsonReader); // 验证读取结果 if (company != null && company.Employees != null) { Console.WriteLine($"读取到公司名:{company.CompanyName},员工数:{company.Employees.Count}"); } }
3. 超大文件的额外优化
如果员工数据量极大,可考虑逐行读取员工对象,避免一次性加载所有数据到内存:
using (var stream = new FileStream(@"D:\large_company.json", FileMode.Open, FileAccess.Read)) using (var reader = new StreamReader(stream)) using (var jsonReader = new JsonTextReader(reader)) { jsonReader.SupportMultipleContent = true; var serializer = JsonSerializer.CreateDefault(settings); var company = new CompanyDetails(); company.Employees = new List<Employee>(); while (jsonReader.Read()) { // 读取公司基础信息 if (jsonReader.TokenType == JsonToken.PropertyName && jsonReader.Value.ToString() == "companyName") { jsonReader.Read(); company.CompanyName = jsonReader.Value.ToString(); } // 读取其他公司属性(如地址、成立时间等)... // 遇到employees数组时,逐行反序列化员工 if (jsonReader.TokenType == JsonToken.PropertyName && jsonReader.Value.ToString() == "employees") { jsonReader.Read(); // 进入数组节点 while (jsonReader.Read()) { if (jsonReader.TokenType == JsonToken.EndArray) break; var employee = serializer.Deserialize<Employee>(jsonReader); company.Employees.Add(employee); } break; } } }
内容的提问来源于stack exchange,提问作者user3296355
相关产品推荐
相关产品推荐

