Config文件格式对比 TOML YAML JSON INI

在机器人架构中,配置文件是重要组成部分,难用的配置文件系统会阻碍系统开发进度,我们现在来对比几个主流的配置文件格式:TOML、YAML、JSON、INI。这篇文章并非原创,是很多文章的综合,都在参考中一一给出。

我们从以下几个主要的维度来看各种文件格式:

  1. 可编辑性。可编辑性是指可以在现有的配置文件上增删内容。
  2. 可读性。
  3. C++强类型支持,即配置文件和C++中的类对应。序列化支持主要的容器序。
  4. 支持前后兼容性。
  5. 配置文件引用功能。配置文件支持引用其他配置文件。

INI

INI是出现较早的配置格式,一开始被用在DOS系统上,没有统一语法。它的可读性和可编辑性好。没有C++的强类型支持,不原生支持C++类序列化。不原生支持文件引用。可以视为简单的key-value pair。它是一种伪二维配置格式,维度概念请见附录。总的结论是不推荐使用。有些库支持配置引用。

格式简介

parameter

INI所包含的最基本的“元素”就是parameter;每一个parameter都有一个name和一个value,如下所示:

name = value

sections

所有的parameters都是以sections为单位结合在一起的。所有的section名称都是独占一行,并且sections名字都被方括号包围着([ and ])。在section声明后的所有parameters都是属于该section。对于一个section没有明显的结束标志符,一个section的开始就是上一个section的结束,或者是end of the file。Sections一般情况下不能被nested,当然特殊情况下也可以实现sections的嵌套。

section如下所示:

[section]

comments

在INI文件中注释语句是以分号“;”开始的。所有的所有的注释语句不管多长都是独占一行直到结束的。在分号和行结束符之间的所有内容都是被忽略的。

注释实例如下:

;comments text

当然,上面讲的都是最经典的INI文件格式,随着使用的需求INI文件的格式也出现了很多变种;

INI实例1:

; 通用配置,文件后缀.ini
[common]

application.directory = APPLICATION_PATH  "/application"
application.dispatcher.catchException = TRUE


; 数据库配置
resources.database.master.driver = "pdo_mysql"
resources.database.master.hostname = "127.0.0.1"
resources.database.master.port = 3306
resources.database.master.database = "database"
resources.database.master.username = "username"
resources.database.master.password = "password"
resources.database.master.charset = "UTF8"


; 生产环境配置
[product : common]

; 开发环境配置
[develop : common]

resources.database.slave.driver = "pdo_mysql"
resources.database.slave.hostname = "127.0.0.1"
resources.database.slave.port = 3306
resources.database.slave.database = "test"
resources.database.slave.username = "root"
resources.database.slave.password = "123456"
resources.database.slave.charset = "UTF8"

; 测试环境配置
[test : common]

parser和emitter库

  • configparser
  • iniparse
  • libconfigini
  • Glib

JSON

JSON是一个轻量级的数据交换格式,是一种二维的文件格式。不光光可以用来做配置文件,还可以用来传输各种数据。可读性和可编辑性尚可。支持C++强类型,很多C++库支持序列化为json文件。有些库支持配置引用。

{
  "firstName": "John",
  "lastName": "Smith",
  "isAlive": true,
  "age": 27,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    }
  ],
  "children": [],
  "spouse": null
}

json C++库

  • cereal
  • Rapidjson
  • protobuf

YAML

YAML是一种广泛使用的语言,用于跨不同语言和框架的配置文件。专注于简化XML的XML人员名单帮助生成Common XML,这是一个功能强大的XML子集,为XML创建了数据序列化的替代方案,特别是与Python ,Perl和Ruby。它的可读性和可编辑性感觉比json高,支持C++强类型。YAML文件可视为二维。有些库支持配置引用。有些库支持配置引用。

关于YAML语法的简短事实

.yml文件以’ - ‘开头,标记文档的开始
键值对由冒号分隔
列表以连字符开头
YAML使用具有一个或多个空格的缩进来描述嵌套集合
要在前面的问题中使用YAML,你需要将它包裹在之间—:

---
date: '2016-12-14T21:27:05.454Z'
publishdate: '2016-12-14T21:27:05.454Z'
title: Deep dive into TOML, JSON and YAML
tags:
- toml
- yaml
- json
- front matter
type: article
amp:
  elements: []
article:
  lead: Lorem ipsum.
  category: frontmatter
  related: []
sitemap:
  changefreq: monthly
  priority: 0.5
  filename: sitemap.xml
---

YAML C++库

  • rapidyaml
  • yaml-cpp
  • ariles
  • cereal-yaml

TOML

TOML显然是由Tom - Tom Preston-Werner编写的 - 确切地说。这是一个在麻省理工学院授权的开源项目,目前在Github上有超过5k星。2013年3月发布的第一个TOML版本,使TOML成为三个标准的年轻人。TOML文件可视为二维。没有找到C++强类型支持的库,需要自己写。有些库支持配置引用。

TOML的目标是成为最小的配置文件格式,由于精确的语义,这种格式易于阅读。TOML被设计为无歧义地映射到散列表。TOML应该很容易用各种语言来解析数据结构。

关于TOML语法的简短事实

TOML区分大小写。
TOML文件只能包含UTF-8编码的Unicode字符。
空格表示制表符(0x09)或空格(0x20)。
换行符表示LF(0x0A)或CRLF(0x0D0A)。
要在前面的问题中使用TOML,你需要将它封装在+++如下之间:

+++
date = "2016-12-14T21:27:05.454Z"
publishdate = "2016-12-14T21:27:05.454Z"

title = "Deep dive into TOML, JSON and YAML"
tags = ["toml","yaml","json", "front matter"]

type = "article"

[amp]
    elements = []
    
[article]
    lead = "Lorem ipsum."
    category = "frontmatter"
    related = []

[sitemap]
  changefreq = "monthly"
  priority = 0.5
  filename = "sitemap.xml"
+++

toml C++库

  • toml11
  • cpptoml
  • tomlplusplus

总结

综上考虑,个人觉得YAML在各方面都很出众。可读性和可修改性强。此外还有cereal这样的C++库支持,推荐使用。此外,直接使用C++来定义config缺乏扩展性,推荐使用protobuf或者flatbuf这样的DSL语言来定义配置文件并生成C++代码。

附录

维度概念

这个概念是从一篇帖子上看到的,根据文件的延展性 , 大致将定义文件分以下几种:

一维

即简单的key-value pair。

[key-value]
     |
[key-value]
     |
[key-value]
     |
    ...
    
     ↑
    [y轴]

二维

二维文件可x轴、y轴自由延伸。此类文件的值(value)数据结构从单纯的值变成对象 , 即key-object , 对象当中可以存放值、数组、键等等 , 通过存放键key从而获得x轴延伸能力。

[  key  ]                   	
    |--[key]--[key]--[key]--[...]--[value]   ←x轴
[key-value]
    |
[key-value]
    |
[key-value]
	|
  [...]
    ↑
   y轴

伪二维

[section]                    ←x轴延伸了一个单位
     |---[key-value]
     |---[key-value]
     |---[key-value]
    ...
    
     ↑
    [y轴]

三维

三维文件则是在二维之上 , 键key的数据机构从单纯的值变成对象 , 从而获得z轴延伸能力。而当键key中可存放键key时 , z轴可无限伸展。

[  key  ]                   	
    |--[key]--[key]--[key]--[...]--[value]   ←x轴
[key-value]             \
    |				   [key]
[key-value]				   \
    |					  [key]
[key-value]                  \
	|						[....]  ←z轴
  [...]
    ↑
   y轴

伪三维

[  key  ]                   	
    |--[key]--[key]--[key]--[...]--[value]   ←x轴
[key-value]             \
    |				 [attribute] ←z轴延伸了一个单位
[key-value]				  
    |					
[key-value]               
	|						
  [...]
    ↑
   y轴

参考

  • 配置文件 INI、YAML、TOML、JSON、XML等比较
  • ini wikipedia
  • ini文件格式和读取
  • 深入对比TOML,JSON和YAML

作者:不俍
链接:https://zhuanlan.zhihu.com/p/654742516
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(json,java,数据库)