配置文件格式选型:YAML vs JSON vs INI

说实话,刚开始接触 GTY 参数配置那会儿,我根本没把配置文件格式当回事。随便选一个,写进去能跑就行。结果呢?有次项目交付,甲方要求所有参数必须带中文注释,而我们的 JSON 文件...嗯,你懂的,// 和 /* */ 统统不认。那叫一个惨。从那以后我就明白了一个道理——选配置文件格式,跟选编程语言一样,没有最好,只有最合适。

三种格式的“画像”

先给各位一个整体印象。我习惯用一个比喻:INI 是口袋里的小刀,简单直接;JSON 是瑞士军刀,标准化但有点冰冷;YAML 是折叠工兵铲,功能强大但用不好容易伤着自己。下面我们把它们拆开来看看。

INI:元老级的简单

INI 格式起源于 Windows 早期,结构就是「节 + 键值对」。没有任何嵌套,不支持数组、列表、注释也有多种方言。适合极轻量级的配置。

; 这是 INI 注释(分号开头)
[display]
resolution = 1920x1080
fullscreen = true

[capture]
fps = 60
codec = h264

优点:肉眼可读,人类写错很难。我曾在嵌入式设备上用它做参数转发,节省了解析库的依赖。

缺点:一有层级关系就歇菜。比如你要描述「摄像头 A 的曝光参数」和「摄像头 B 的曝光参数」,INI 只能靠节名区分,字段名还得重复,代码里处理起来特别拧巴。

JSON:互联网的通用语

JSON 现在是 API 通信的默认格式。它的结构清晰,数组、对象、嵌套都支持。几乎所有语言都有内置解析器,没有依赖问题。

{
    "display": {
        "resolution": "1920x1080",
        "fullscreen": true
    },
    "capture": {
        "fps": 60,
        "codec": "h264"
    }
}

优点:标准化,跨语言解析零障碍。配合 schema 校验工具,可以自动检查配置完整性。

缺点:没有注释!这是它最大的硬伤。还有,JSON 语法对逗号极其严格——末尾多一个逗号就报错。我记得有一次调试 GTY 的参数字典,复制了一个 JSON 片段,漏删了最后一个逗号,卡了半天才发现。

YAML:人类优先,机器后行

YAML 的设计目标就是「对人类的友好程度要超过 JSON」。缩进代替花括号,支持注释,支持多行字符串,支持锚点和别名。GTY 的官方样例文件大部分是 YAML 格式。

# 这是 YAML 注释
display:
  resolution: 1920x1080
  fullscreen: true
capture:
  fps: 60
  codec: h264

优点:写起来最快,可读性最好,注释自由。团队协作时,每个人都可以在配置里写备注,说明这个参数为什么这么设。

缺点:缩进敏感。一个 Tab 和四个空格混用,解析器直接罢工。而且 YAML 的隐式类型转换很坑——比如 on: true 会被解析成布尔值,如果你期望的是字符串 "on",那就完了。

核心维度对比

维度 INI JSON YAML
语法复杂度 极低 中 中高
嵌套支持 不支持 深度嵌套 深度嵌套
注释 支持 (;) 不支持 支持 (#)
数据类型 仅字符串 字符串/数字/布尔/null/数组/对象 字符串/数字/布尔/数组/对象/多行字符串
解析性能 极快 快 较慢(需处理缩进)
跨语言兼容 需第三方库 内置 需第三方库(普遍)
人类可读性 好 一般 优秀
机器可编辑性 好 优秀 普通(格式易被破坏)
GTY 官方推荐度 低(历史兼容) 中 高
典型场景 启动参数、系统默认值 API 配置、配置文件交换 复杂参数手册、团队协作

如何选?我的一套决策逻辑

其实你不用背下表格里所有内容。我自己做选择时,就三个问题:

  1. 需要注释吗? 只要有团队协作或未来维护需求,去掉 JSON。剩下 YAML 和 INI。
  2. 配置有层级吗? 超过两层嵌套,果断放弃 INI。剩下 YAML。
  3. 配置需要被程序自动生成或修改吗? 如果工具链用 Python 的 json 模块,JSON 更稳妥;如果用 Python 的 yaml 模块且能控制缩进,YAML 也可。
我的小建议: 对于 GTY 这类参数繁多的仿真系统,我主力用 YAML,但会要求团队统一缩进风格(2空格,禁止Tab)。另外会在代码里加一个 YAML 校验步骤,避免缩进问题导致运行时崩溃。

避坑指南:我踩过的三个雷

曾经,我在一个多摄像头同步项目中,用 INI 写所有参数。摄像头数量从 4 路扩展到 16 路,配置文件从 50 行膨胀到 800 行,节名重复、字段冗余,维护起来想哭。后来重构为 YAML,分组嵌套 + 锚点复用,代码量减少 40%。

还有一次,我在 JSON 配置里写了注释,生产环境读取失败。原因是同事用编辑器自动添加了 //,而解析器直接抛异常。排查了一下午。从那以后我强制在 CI 流程里加了 JSON 语法校验。

另一个事:YAML 的 !include 是不标准的,不同解析器实现不同。我曾试过用 yaml.load() 加载一个包含了 !include 指令的文件,结果直接报错。如果你需要拆分配置文件,建议用 Python 自己写合并逻辑,别依赖 YAML 扩展。

图解:选择配置文件格式的决策流程

下面这张图整理了我上面说的思路,画成 SVG 方便你打印出来贴在工位上。

配置文件格式选型决策流程 开始选择格式 问题1 需要注释? 是 否 有层级 嵌套? YAML 是否自动 生成? JSON INI 是否自动 生成? JSON 有层级 嵌套? YAML INI 说明:YAML 适合需要注释且有层级的场景;JSON 适合机器自动生成或交换; INI 只适合扁平、简单的配置,嵌套复杂时尽早重构。

写在最后:实践中的“潜规则”

纸上谈兵没用,干活时你还会碰到这些细节:

  • GTY 官方文档推荐 YAML,但它的示例里有时混用 JSON。别模仿,保持统一。
  • 版本控制友好度:YAML > INI > JSON。因为 JSON 一行太长,diff 不好看;YAML 的行粒度细,改一个参数只影响一两行。
  • 性能敏感场景:如果 GTY 参数配置需要频繁热加载(比如实时调试),建议用 JSON 或 INI,解析开销远低于 YAML。
一句话总结:没有万能格式。YAML 给人类看,JSON 给机器看,INI 给历史遗留项目。你在 GTY 项目里,个人推荐 YAML + 严格缩进约定 + 自动化校验。

好了,每种格式的优劣势和选型逻辑,我基本讲清楚了。你手头如果有 GTY 的配置,不妨打开看看用的是哪种,对照今天的思路评估一下是否需要迁移。