CodeGym /课程 /C# SELF /主要的序列化格式: XML,

主要的序列化格式: XML, JSON, CSV, Protobuf

C# SELF
第 43 级 , 课程 2
可用

1. 为啥要选择格式?简短提醒

任何 .NET 对象在内存里都是一堆地址、引用、字段、内部结构和其他“机器里面的东西”。但你不能就这样直接把它存成文件:文件要有一种结构,别的程序也能读(最好也能写)。这时候就得选序列化格式了。

序列化格式的主要任务:

  • 紧凑:磁盘空间或网络传输速度。
  • 可读性(给人看!):能不能用文本编辑器打开并理解内容。
  • 通用性:能不能和其它系统、语言集成。
  • 支持复杂结构:嵌套、集合、引用、类型等。
  • 安全性和兼容性。

2. 二进制序列化 (Binary Serialization)

二进制序列化把数据表示成“原始”的字节流。想象你不仅把东西装箱,还把箱子打了水泥——很快、很紧凑,但如果没工具你连自己的袜子都找不到。

// 示例仅作历史参考:
using System.Runtime.Serialization.Formatters.Binary;

// ... 创建对象
var user = new User { Name = "伊万", Age = 42 };

// 序列化
using var fs = new FileStream("user.bin", FileMode.Create);
var formatter = new BinaryFormatter();
formatter.Serialize(fs, user);

优点:

  • 紧凑:占用最少空间,速度很快。
  • 内建支持“原生”的 .NET 类型。

缺点:

  • 格式完全不可读——在记事本里打开你会进入“黑客世界”(也就是会看到不可读字符)。
  • 绝对地 不通用:只适合 .NET(而且通常只对相同版本有效)。
  • 对版本间兼容性很脆弱。

以前用在哪儿?

在 .NET 内部,需要在同一台机器的进程间快速“转储”对象时会用。现在强烈 建议这么做,特别是当你关心安全性和长期维护时。在现代项目中使用 BinaryFormatter 是不好的实践。

3. XML 格式 (Extensible Markup Language)

XML是人和机器都能读的基于标签的格式,像 HTML,但没有那些关于 <body> 的笑话。

<User>
  <Name>伊万</Name>
  <Age>42</Age>
</User>

序列化示例:

using System.Xml.Serialization;

var user = new User { Name = "伊万", Age = 42 };

var serializer = new XmlSerializer(typeof(User));
using var fs = new FileStream("user.xml", FileMode.Create);
serializer.Serialize(fs, user);

优点:

  • 可读:可以打开文件肉眼看出结构。
  • 通用:很多语言和程序都能读 XML。
  • 灵活(支持 schema、校验、命名空间等)。
  • 适合复杂结构和嵌套对象。

缺点:

  • “啰嗦”且笨重:占空间、消耗流量。
  • 解析比二进制格式慢。
  • 对某些类型(比如日期和时间)序列化可能不精确。
  • 对某些集合或非标准对象需要额外配置。

在哪里用?

企业系统间的数据交换、配置文件、需要严格结构的集成场景。

4. JSON 格式 (JavaScript Object Notation)

JSON是紧凑、轻量、易读的格式,来自 JavaScript 世界,凭借简洁性和易用性几乎统治了数据交换领域。

{
  "Name": "伊万",
  "Age": 42
}

序列化示例:

using System.Text.Json;

var user = new User { Name = "伊万", Age = 42 };

string json = JsonSerializer.Serialize(user);
File.WriteAllText("user.json", json);

优点:

  • 对人和机器都很可读。
  • 容易和 web 技术集成(API、JavaScript 等)。
  • 比 XML 更紧凑。
  • 现代库下序列化/反序列化速度很快(System.Text.Json, Newtonsoft.Json)。

缺点:

  • 不支持注释(你的 JSON 不能自嘲)。
  • 结构上有限制:不能序列化对象间引用或某些复杂类型(比如非字符串键的字典)。
  • 不同实现对日期/时间的处理可能不一致。

在哪里用?

几乎所有需要跨平台数据交换的地方:web 服务、移动应用、REST API 等。

5. CSV (Comma-Separated Values)

CSV是简单的文本格式,把数据表示成表格(行和列),字段用逗号或其他分隔符分开。

Name,Age
伊万,42
奥尔加,27

手工写 CSV 的示例:

// 为了简单,用普通 StreamWriter 写
var lines = new List<string>
{
    "Name,Age",
    "伊万,42",
    "奥尔加,27"
};
File.WriteAllLines("users.csv", lines);

优点:

  • 被大量程序支持(Excel、Google Docs、数据库等)。
  • 简洁,适合表格型数据。

缺点:

  • 不适合嵌套或复杂对象(只适合“扁平”结构)。
  • 不保存类型信息(所有都是字符串)。
  • 当数据包含逗号、引号或换行时,转义问题会很麻烦。

在哪里用?

数据库间的导入/导出、简单记录的交换、应用数据导出。

6. 强类型交换的协议和格式

Protocol Buffers (protobuf)MessagePack 是带契约(schema)的二进制序列化格式,使序列化更紧凑、更快。它们需要预先描述数据结构的 schema。

简化的 protobuf 示例:

不属于 .NET 标准,需要包 Google.Protobuf

message User {
  string name = 1;
  int32 age = 2;
}

优点:

  • 极高的速度和最紧凑的表示。
  • 跨平台(很多语言都支持 protobuf)。

缺点:

  • 学习和配置更复杂。
  • 需要根据 schema 生成代码。
  • 如果不是每秒百万级消息,很多时候用不着。

在哪里用?

高负载系统、微服务间数据交换、游戏、IoT。

7. 有用的细节

格式对比表

格式 可读性 紧凑性 通用性 复杂对象 .NET 9 标准 安全性
Binary (.NET)
XML
JSON 部分
CSV
Protobuf 最佳

怎么为你的应用选格式?

需要保存复杂数据结构且你希望人能读 — 用 XML 或 JSON。

需要在你控制的服务间快速传输大量数据 — 考虑 protobuf 或 MessagePack。

为 Excel 或数据库导出报表 — 用 CSV。

写服务或 CI/CD 的配置文件 — YAML 会很方便你。

紧凑、速度和对象间引用非常关键?那就找二进制格式,但别忘了安全性和兼容性的缺点。

8. 棘手的点和常见错误

如果你因为“保密”就把数据存为二进制,记住:二进制转存不等于安全。攻击者仍然可以分析这个字节流。需要安全时,还是用加密。

常见问题:在处理文本格式(XML/JSON/CSV)时忘记编码——请使用 UTF-8。并非所有编辑器和系统都喜欢 BOM(字节顺序标记)。

XML 看起来“老”,但它在契约式协议里很棒,那里结构校验很重要(比如 XSD schema);而 JSON 适合快速、灵活的数据交换。

序列化复杂对象集合时,并非所有格式都正确支持嵌套或递归结构。JSON 和 XML 对数组与列表支持良好,CSV 则不行。

2
任务
C# SELF, 第 43 级, 课程 2
已锁定
对象的JSON序列化
对象的JSON序列化
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION