【配置文件】INI、JSON、YAML、TOML四种格式对比?
INI、JSON、YAML、TOML四种比较常见配置文件对比。
INI
优点
- 简单直观:适合存储简单的键值对数据。
- 易于编辑:文本编辑器即可修改。
- 广泛应用:在Windows环境中尤为常见。
- 支持分节:通过
[section]
划分不同组别的配置。
缺点:
- 不支持复杂数据结构:如列表、字典等。
- 格式非标准化:不同软件对INI的支持细节可能有差异。
语法
节
; 用来组织相关设置的一个逻辑单位 ; 节名可以包含字母、数字和下划线,但不能以数字开头,也不支持空格 [SectionName]
键值对
; 在每个节下面,可以定义多个键值对,每对键值占一行,格式为key=value。 KeyName1=Value1 KeyName2=Value2
注释
; 支持以 ; 分号作为注释标志 # 也支持以 # 作为注释标志
- 空白字符
键和值之间或节名后的空白会被忽略。可以合理使用空白字符增加可读性。
示例
;这是一段全局配置文件 [global] name = zhanganjin email = anjin@zhanganjin.com ;这是一段其他配置 [blog] url1 = www.zhanganjin.com url2 = blog.zhanganjin.com
JSON
优点
- 标准化:有明确的RFC标准。
- 广泛支持:几乎所有现代编程语言都有解析库。
- 数据结构丰富:支持对象(键值对)、数组等复杂结构。
- 易于机器解析:格式严格,错误容易检测。
缺点:
- 可读性一般:特别对于复杂的嵌套结构。
- 不支持注释:标准JSON不包含注释功能。
语法
- 数据结构
支持Object
(键值对、字典、对象)和Array
(数组),且可以相互嵌套 - 注释
json中没有注释
- 数据结构
示例
{ "global":{ "name":"zhanganjin", "email":"anjin@zhanganjin.com", "blog":[ "www.zhanganjin.com", "blog.zhanganjin.com" ] } }
YAML
优点
- 高度可读性:使用空白和缩进,格式美观。
- 灵活性高:支持复杂数据结构,如列表、映射、锚点和别名。
- 支持注释:方便文档化配置。
- 简洁:相对于XML,更少的冗余。
缺点:
- 空白敏感:缩进错误会导致解析失败。
- 安全性问题:不当处理可能引入注入风险。
语法
- 大小写敏感
- 缩进
使用空格进行缩进,推荐使用2个空格作为一级缩进。不允许使用制表符(tab)进行缩进 数据结构
- 标量:单个的值,如字符串、数字、布尔值、日期等。字符串默认不需要引号包围,但包含特殊字符或空格开头/结尾时应使用引号
- 列表:用破折号 - 开头并缩进表示,列表项可以是任意数据类型。
- 映射:键值对集合,键后面紧跟冒号 :,然后是值,键必须是字符串,而值可以是任意类型。映射项通过缩进进行分组。
- 注释
使用#
进行单行注释
示例
global: name: zhanganjin email: anjin@zhanganjin.com blog: - www.zhanganjin.com - blog.zhanganjin.com
TOML (Tom's Obvious, Minimal Language)
优点
- 易读易写:设计注重人类可读性。
- 键值对清晰:明确的键值对语法,易于理解。
- 支持注释:使用
#
进行单行注释,提高文档性。 - 类型推断和声明:支持显式声明变量类型,减少误解。
缺点:
- 相对年轻:相比INI和JSON,生态和工具支持可能较少。
- 复杂度:虽然灵活性高,但对于简单配置可能显得过度设计。
语法:
- 数据结构
键值对是TOML的基本组成单元,格式为 key = value。键必须是字母、数字、下划线组成的字符串,且不能以数字开头。值可以是字符串、数字、布尔值、日期时间、数组或表。 字符串
- 单行字符串不需要引号,除非包含特殊字符或需要保留空白。
- 多行字符串用三个单引号
'''
或三个双引号"""
包围。
- 布尔值和日期时间
布尔值用true
或false
表示,日期时间遵循ISO 8601
标准。 - 数组
用方括号[]
包围,元素间以逗号,
分隔。TOML支持同质数组(即所有元素类型相同) 表
- 表是键值对的集合,用来组织相关配置。定义表使用方括号
[Table]
,表名后跟一个空行开始表的内容。 - 嵌套表使用点分隔符表示,如
[Table.Subtable]
- 表是键值对的集合,用来组织相关配置。定义表使用方括号
- 表数组
表也可以定义为数组,通过在表名后加方括号并指定索引或范围来实现,如[Table.[index]]
- 注释
单行注释使用井号#
- 数据结构
示例
[global] name = "zhanganjin" email = "anjin@zhanganjin.com" blog = [ "www.zhanganjin.com", "blog.zhanganjin.com" ]