如何在C#中解析40GB+超大JSON文件以避免内存溢出异常
超大JSON文件的分段解析方案
完全可以像处理大型XML那样流式分段解析超大JSON文件,避免内存溢出问题。你的核心问题在于当前代码的解析逻辑有误,同时没有遵循"解析一个、处理一个、释放一个"的流式处理原则。
当前代码的问题
- 实体类属性不匹配:JSON中的字段是
data,但你的NetworkElement类定义的是lstData,会导致数据无法正确映射。 - 解析目标错误:你的JSON是多个独立的
NetworkElement对象,而非List<NetworkElement>,每次解析应针对单个对象。 - 未做流式处理:如果把所有解析后的对象存入集合,最终还是会耗尽内存,应该解析一个就处理一个(比如写入数据库、生成统计结果),不长期持有对象。
修正后的流式解析代码
using Newtonsoft.Json; using System.IO; class Program { static void Main(string[] args) { JsonSerializer serializer = new JsonSerializer(); // 流式读取文件,避免一次性加载到内存 using (FileStream s = File.Open(@"\\As21382dxbdb05\enrm\kafkafile\kafka.txt", FileMode.Open)) using (StreamReader sr = new StreamReader(s)) using (JsonReader reader = new JsonTextReader(sr)) { reader.SupportMultipleContent = true; // 允许读取多个独立JSON内容 // 循环解析每个独立的JSON对象 while (reader.Read()) { // 解析单个NetworkElement对象 NetworkElement element = serializer.Deserialize<NetworkElement>(reader); // 这里写你的处理逻辑:比如写入数据库、计算统计值等 // 处理完后该对象会被GC回收,不会占用大量内存 ProcessElement(element); } } } // 示例处理方法,根据你的需求替换 static void ProcessElement(NetworkElement element) { // 比如输出日志、写入数据库等 System.Console.WriteLine($"处理元素:{element.networkElementPath}"); } } // 修正后的实体类,确保属性名与JSON字段匹配 public class NetworkElement { public string networkElementPath { get; set; } public string recordTypeName { get; set; } public long collectionTimeEpoch { get; set; } // JSON里是数字类型,用long更合适 public List<Data> data { get; set; } // 改为与JSON字段一致的名称 } public class Data { public string name; public double value; public string type; public string unit; }
关键注意事项
- 禁止全局集合存储:绝对不要把所有
NetworkElement对象存入一个List,否则40GB的文件最终还是会撑爆内存。 - 属性类型匹配:
collectionTimeEpoch在JSON中是数字(1713520800),用long而非string可以避免不必要的类型转换问题。 - 流式读取核心:
JsonTextReader是逐字符读取的,不会一次性加载整个文件到内存,配合SupportMultipleContent = true就能识别多个独立的JSON对象。
内容的提问来源于stack exchange,提问作者peter
相关产品推荐
相关产品推荐

