概述

数据交换格式是人、程序、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: true

YAML 使用缩进表示层级关系,列表以破折号(-)开头,键值对以冒号加空格分隔。

适用场景

  • 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:00Z

TOML 支持表格、内联表、数组等结构,语法清晰直观。

适用场景

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;
}

格式对比

特征 / 格式INIYAMLXMLJSONTOMLCSV
可读性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
可写性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
数据类型⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
注释支持
适用场景简单配置DevOps 配置企业数据交换Web API项目配置表格数据

如何选择

  • 简单配置:选择 INITOML。INI 胜在朴素,TOML 胜在类型更明确。
  • 复杂层次结构:选择 YAML,但要控制复杂度。CI、Kubernetes、Ansible 这类场景适合 YAML;业务数据交换要警惕缩进、隐式类型和反序列化风险。
  • Web API 数据交换:选择 JSON。几乎所有语言都有原生支持,生态最完善。需要注释时考虑 JSONC 或 JSON5,但不要把它们误当成标准 JSON API。
  • 表格数据导入导出:选择 CSV。它兼容性最广,但类型信息弱,分隔符、引号、换行和编码要提前约定。
  • 高性能服务间通信:选择 Protobuf。它适合强契约和高性能,但牺牲直接可读性,需要 schema 管理。
  • 现代项目配置:选择 TOMLpyproject.tomlCargo.toml 已把 TOML 推成不少语言生态的项目配置默认选项。

我的默认判断是:给机器和 API 用 JSON,给人维护的工程配置用 TOML 或 YAML,给表格交换用 CSV,给强类型高性能服务用 Protobuf。格式一旦进入项目,就等于承诺了一套解析和演进边界。