You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:36:17