跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

C#序列化对象到文件 C#如何将对象保存为二进制或JSON文件

BinaryFormatter 已被弃用且不安全,应改用 System.Text.Json(推荐)、MessagePack 或 Protocol Buffers;JSON 适合文本数据,二进制内容需 Base64 编码或单独存储。 用
BinaryFormatter
保存二进制文件?别用了 从 .NET Core 3.0 开始,
BinaryFormatter
已被标记为过时(obsolete),且默认禁用——它存在严重反序列化安全风险,微软明确不推荐在任何新项目中使用。即使你强制启用,.NET 6+ 也会在运行时抛出
NotSupportedException
。 如果你真需要二进制序列化(比如老系统兼容、高性能本地缓存),可改用
System.Text.Json
的二进制编码变体(需搭配
JsonSerializerOptions
+
Utf8JsonWriter
写入
MemoryStream
),但更现实的选择是:直接用 JSON,或换用
MessagePack
这类安全、紧凑的二进制格式。 不要在生产环境写
new BinaryFormatter().Serialize(...)
若必须读取旧的
.bin
文件,用
BinaryFormatter
仅限于可信、隔离的脱机场景,并确保反序列化类型白名单严格控制 替代方案优先级:JSON(通用)→ MessagePack(紧凑+快)→ Protocol Buffers(跨语言) 用
System.Text.Json
序列化到 JSON 文件(推荐)
System.Text.Json
是 .NET 5+ 默认内置的高性能 JSON 库,无需安装 NuGet,支持异步、流式读写、自定义转换器,且默认忽略循环引用(不会崩溃)。 最简保存方式:
var options = new JsonSerializerOptions { WriteIndented = true }; File.WriteAllText("user.json", JsonSerializer.Serialize(user, options));
注意几个关键点:
WriteIndented = true
仅用于调试,生产环境建议关掉以减小体积 若对象含
DateTime
,默认序列化为 ISO 8601 字符串(如
"2024-05-20T14:30:00Z"
),无需额外配置 私有字段默认不序列化;要包含,加
[JsonPropertyName("xxx")]
或设置
IncludeFields = true
和
DefaultIgnoreCondition = JsonIgnoreCondition.Never
遇到
NotSupportedException
(如含
DBNull
、
IntPtr
或自定义不可序列化类型),说明该类型没实现
JsonConverter
,需手动注册转换器 用
Newtonsoft.Json
(Json.NET)保存时要注意什么 虽然
System.Text.Json
是官方推荐,但很多老项目仍依赖
Newtonsoft.Json
。它更灵活,但也更容易踩坑。 C知道 CSDN推出的一款AI技术问答工具 下载 基础写法:
File.WriteAllText("user.json", JsonConvert.SerializeObject(user, Formatting.Indented));
常见陷阱: 默认会序列化所有 public 属性和字段,包括
get; set;
自动属性的 backing field(如果用了
[JsonIgnore]
就没事)
DateTime
默认按本地时区输出,易引发时区混淆;建议统一用
JsonConvert.SerializeObject(..., new JsonSerializerSettings { DateTimeZoneHandling = DateTimeZoneHandling.Utc })
若对象里有
JObject
或
JArray
,它们会被原样嵌入,但后续用
System.Text.Json
读取会失败——混用库时务必统一序列化格式 大对象(>85KB)可能触发 LOH(Large Object Heap)分配,频繁操作影响 GC 性能;此时应改用
JsonTextWriter
流式写入 异步保存和错误处理不能省 直接调用
File.WriteAllText
会阻塞线程,尤其在 UI 或 ASP.NET Core 请求线程中容易拖慢响应。真正可用的写法是异步 + 异常包裹:
try { var json = JsonSerializer.Serialize(user, new JsonSerializerOptions { WriteIndented = false }); await File.WriteAllTextAsync("user.json", json); } catch (UnauthorizedAccessException) { // 检查目录是否有写权限,或文件是否被其他进程占用(如 Excel 正在打开该文件) } catch (IOException ex) when (ex.Message.Contains("The process cannot access the file")) { // 文件被独占锁定,考虑加重试或提示用户关闭相关程序 }
另外,路径必须合法:
Directory.CreateDirectory(Path.GetDirectoryName("data/user.json"))
要提前执行,否则
File.WriteAllTextAsync
会直接抛
DirectoryNotFoundException
。 最后提醒:JSON 不适合存二进制数据(如图片、音频)。这类内容应 Base64 编码后作为字符串字段存入,但体积膨胀约 33%;更合理的方式是单独保存为文件,JSON 中只存路径或哈希值。

相关文章