system.text.json流式写入json文件最轻量,.net core 3.0+原生支持;应使用serializeasync配合filestream避免内存峰值,指定writeindented=true便于调试,注意datetime默认iso格式及streamwriter提前释放问题。

用 System.Text.Json 直接写入文件最轻量
不需要额外 NuGet 包,.NET Core 3.0+ 和 .NET 5+ 原生支持。关键不是“先序列化成字符串再写”,而是用 JsonSerializer.SerializeAsync 配合 FileStream 流式写入,避免大对象引发的内存峰值。
实操建议:
- 始终指定
new JsonSerializerOptions { WriteIndented = true },方便调试和人工查看 - 若对象含
DateTime,注意默认序列化格式是 ISO 8601(如"2024-05-20T09:30:00Z"),无需额外配置 - 遇到
NotSupportedException: Cannot write to a closed TextWriter,大概率是StreamWriter被提前 dispose,应确保FileStream和序列化共用同一作用域
var options = new JsonSerializerOptions { WriteIndented = true };
await using var stream = File.Create("data.json");
await JsonSerializer.SerializeAsync(stream, myObj, options);
处理 Newtonsoft.Json(Json.NET)的兼容写法
老项目还在用 Newtonsoft.Json?它不支持直接流式序列化到文件,但可以避免中间字符串分配:用 JsonTextWriter 包装 FileStream。
常见错误现象:
- 用
JsonConvert.SerializeObject(obj)再File.WriteAllText→ 大对象时 GC 压力陡增 - 忘记设置
textWriter.CloseOutput = false→ 文件末尾多出一个空字节或截断 -
DateTime默认输出为/Date(1716203400000)/格式 → 应显式设dateFormatHandling: DateFormatHandling.IsoDateFormat
using var stream = File.Create("data.json");
using var writer = new StreamWriter(stream);
using var jsonWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
var serializer = new JsonSerializer { DateFormatHandling = DateFormatHandling.IsoDateFormat };
serializer.Serialize(jsonWriter, myObj);
需要控制字段忽略或重命名?别硬编码 [JsonIgnore]
运行时动态决定哪些属性写入 JSON,比加一堆特性更灵活。比如导出时隐藏敏感字段、或按角色过滤字段。
实操要点:
-
System.Text.Json用自定义JsonConverter<t></t>或继承JsonSerializerContext配置JsonSerializerOptions -
Newtonsoft.Json更直接:用ContractResolver子类,在CreateProperty中判断memberInfo.Name并设shouldSerialize = false - 别在序列化前手动克隆对象删字段——破坏原始状态,且无法处理嵌套引用
异步写入失败却没报错?检查 FileStream 的 FileShare
常见静默失败场景:多个线程/进程同时尝试写同一个 JSON 文件,File.Create 默认以 FileShare.None 打开,后继写入会卡住或抛 IOException 但被吞掉。
必须明确:
- 写文件时不要用
File.OpenWrite,它不支持异步;坚持用File.Create或FileStream构造函数 - 如果需并发写不同文件,确保路径唯一;若真要覆盖同一文件,加
lock或用SemaphoreSlim控制写入节奏 - 捕获
IOException后检查ex.HResult == -2147024864(即 ERROR_SHARING_VIOLATION),这是 Windows 下共享冲突的典型信号






