概述
数据交换格式是人、程序、CI、Agent 和远程服务之间的契约。选择格式不是审美问题,而是在可读性、可解析性、类型能力、注释需求、性能和安全边界之间做取舍。无论是本地配置、API 响应、日志、数据导入,还是服务间通信,格式选错都会把后续自动化变得脆弱。
数据交换格式的主要作用包括:
- 提高自动化水平:自动部署和管理工具广泛依赖结构化数据来执行复杂的操作。
- 促进团队协作:统一的格式使得不同背景的开发者能够轻松理解和修改数据。
- 增加应用的灵活性:通过外部配置文件,应用程序可以不需修改代码即可适应不同环境。
- 支持环境隔离:不同环境(如开发、测试和生产)可以使用不同的配置,而不会互相干扰。
INI
INI 文件格式(Initialization File)起源于 Windows 操作系统,用于存储程序的设置。它由节、键和值组成,结构简单直观,适合不需要复杂层次结构的场景。
基础语法
[database]
server = 192.168.1.1
port = 3306
username = admin注释可以通过在行首添加分号(;)或井号(#)来实现。
适用场景
- 应用程序的简单配置(如游戏的视频设置)
- 传统服务器软件的基础属性配置
- 开发环境设置(如 PHP 的
php.ini)
XML
XML(eXtensible Markup Language)是一种标记语言,旨在存储和传输数据。它允许用户定义自己的标记元素,非常适合跨平台的数据交换和文档编制。
基础语法
<person>
<name>John Doe</name>
<age>30</age>
<address city="New York" />
</person>XML 使用标签定义元素,支持属性存储额外信息,元素可以嵌套形成复杂的树状结构。
适用场景
- 企业级系统的数据交换和配置
- Web 服务(SOAP 协议使用 XML 编码消息)
JSON
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,也易于机器解析和生成。它是现代 Web API 的事实标准。
基础语法
{
"users": [
{ "name": "John Doe", "age": 30 },
{ "name": "Jane Smith", "age": 25 }
],
"settings": {
"color": "blue",
"enabled": true
}
}JSONC (JSON with Comments)
JSONC 在标准 JSON 基础上增加了注释支持,VS Code 的配置文件即使用此格式:
{
// 编辑器字体设置
"editor.fontSize": 14,
"editor.tabSize": 2,
/* 多行注释:主题配置 */
"workbench.colorTheme": "Default Dark+"
}JSON5
JSON5 进一步放宽了语法限制,支持尾逗号、单引号、无引号键名等更宽松的语法:
{
// 支持注释
name: 'John Doe', // 无引号键名 + 单引号值
skills: ['rust', 'ts',], // 尾逗号合法
}YAML
YAML(YAML Ain’t Markup Language)是一种以数据为中心的序列化格式,设计理念是易于阅读和书写。它广泛应用于容器编排和 DevOps 场景。
注意:安全陷阱:YAML 的
!!python/object等标签可以反序列化并执行任意代码。绝对不要对不信任来源的 YAML 使用PyYAML.load()(应使用safe_load())。其他语言的反序列化库也存在类似风险。YAML 适合人写配置,但不适合把不可信输入直接当作对象恢复。
基础语法
users:
- name: John Doe
age: 30
- name: Jane Smith
age: 25
settings:
color: blue
enabled: trueYAML 使用缩进表示层级关系,列表以破折号(-)开头,键值对以冒号加空格分隔。
适用场景
- Kubernetes 容器和服务配置(Pods、Deployments)
- CI/CD 管道定义(GitLab CI、GitHub Actions)
CSV
CSV(Comma-Separated Values,逗号分隔值)是最古老也最广泛使用的表格数据格式。它以纯文本形式存储表格数据,每行一条记录,字段以逗号分隔。
基础语法
name,age,city
John Doe,30,New York
Jane Smith,25,London
"Smith, Bob",28,"San Francisco"包含逗号或换行符的字段需要用双引号包裹,双引号本身通过 "" 转义。
常见变体
- TSV(Tab-Separated Values):使用制表符分隔,避免数据中包含逗号时的转义问题
- RFC 4180:CSV 的正式标准,定义了换行符、引号转义等规范
适用场景
- 数据导入导出(数据库、电子表格)
- Excel 兼容的数据交换
- 数据分析和机器学习数据集
TOML
TOML(Tom’s Obvious, Minimal Language)是一种旨在简单明确的数据序列化格式。它的设计哲学是易于阅读与编写,且语义明确无歧义。
基础语法
[database]
server = "192.168.1.1"
ports = [8001, 8002]
enabled = true
[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00ZTOML 支持表格、内联表、数组等结构,语法清晰直观。
适用场景
Python 的 pyproject.toml 和 Rust 的 Cargo.toml 使 TOML 成为现代项目的标准配置文件格式,在新兴语言生态中占据主导地位。
Protocol Buffers (Protobuf)
Protocol Buffers 是 Google 开发的高效二进制序列化格式。与上述文本格式不同,Protobuf 使用 .proto 文件定义数据结构,编译后生成强类型的序列化/反序列化代码。它的体积更小、解析更快,但牺牲了人类可读性。
适用场景
- gRPC 服务间通信
- 高性能微服务架构
- 需要节省带宽和存储的场景
示例 .proto 文件:
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
repeated string emails = 3;
}格式对比
| 特征 / 格式 | INI | YAML | XML | JSON | TOML | CSV |
|---|---|---|---|---|---|---|
| 可读性 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 可写性 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 数据类型 | ⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐ |
| 注释支持 | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
| 适用场景 | 简单配置 | DevOps 配置 | 企业数据交换 | Web API | 项目配置 | 表格数据 |
如何选择
- 简单配置:选择 INI 或 TOML。INI 胜在朴素,TOML 胜在类型更明确。
- 复杂层次结构:选择 YAML,但要控制复杂度。CI、Kubernetes、Ansible 这类场景适合 YAML;业务数据交换要警惕缩进、隐式类型和反序列化风险。
- Web API 数据交换:选择 JSON。几乎所有语言都有原生支持,生态最完善。需要注释时考虑 JSONC 或 JSON5,但不要把它们误当成标准 JSON API。
- 表格数据导入导出:选择 CSV。它兼容性最广,但类型信息弱,分隔符、引号、换行和编码要提前约定。
- 高性能服务间通信:选择 Protobuf。它适合强契约和高性能,但牺牲直接可读性,需要 schema 管理。
- 现代项目配置:选择 TOML。
pyproject.toml和Cargo.toml已把 TOML 推成不少语言生态的项目配置默认选项。
我的默认判断是:给机器和 API 用 JSON,给人维护的工程配置用 TOML 或 YAML,给表格交换用 CSV,给强类型高性能服务用 Protobuf。格式一旦进入项目,就等于承诺了一套解析和演进边界。