常用配置文件格式简析
我大量使用过的配置文件主要有以下几种:
在这些中间,我最喜欢的三种格式是: lua、INI 和 YAML ,最不喜欢的是 JSON 。下面简单的说说它们。
优秀的配置文件
我认为 好的配置文件 必须包含下面几个因素:
1. 规则足够简单 2. 人类友好 在没有任何辅助工具的情况下清晰可读 3. 支持简单的层级关系 4. 允许注释
如果还包含下面几点,则可以认为是 优秀的配置文件:
5. 易于解析(解析库有多种语言实现) 6. 逐行解析 在数据不完整的情况下不影响解析 7. 支持嵌套的层级关系 8. 支持列表和字典 9. 支持类型
lua 和 python
在 lua 开发中,由于 lua 语言的特性,使用一个 lua 文件作为配置文件是很常见也很自然的事情。在使用 quick-cocos2d-x 进行游戏开发的日子里,我大量使用 lua 的这种特性,甚至直接在配置文件中包含简单的逻辑来替换 _G
中的全局变量。而在使用这些配置文件的时候,只需要简单地 require
它们,lua 解释器会帮我们搞定一切。
当然,lua 作为配置文件的这种方便是 lua 解释器提供的,这也限制了 lua 配置文件的通用性。我们应该尽量在 lua 程序中使用 lua 作为配置文件。离开这个框架,则不太合适了。
python 的情况也类似。在 python 中,我将一个 dict 直接 dump 成为字符串,在使用这个配置文件的时候,使用 eval 解析。显然,这样使用并没有 lua 那样方便。
严格来说,这两种格式算不得配置文件。因为它们在特定的语言范畴易用,但缺乏跨语言和跨环境的通用性。例如,如果需要在 Python 中解析 lua 文件,可能需要自己写 解析器 来实现。
然而,我们可以使用语言的解析器来解析它们,可以不需要任何外部库可能直接使用它们,它们还完全符合我上面定义的 “好的配置文件” 标准。在没有其它选择(或不愿意进行选择),不考虑跨语言的前提下,它们用起来是挺不错的。
JSON —— 糟糕
由于 JavaScript 的流行,JSON 当然成了最适合 JavaScript 使用的配置文件。JSON 可以在 JavaScript 中使用 eval()
或者 JSON.parse()
来解析,解析后的内容直接成为 JavaScript 的内置对象。
但是,其实 JSON 不适合作为配置文件使用。根据上面我定义的 好的配置文件 条件来看:JSON 规则简单但不宜读(尤其是复杂的没有格式化过的 JSON),不支持注释,也不能使用较为宽松的语法。
例如,下面这种多余的逗号在 JSON 中被认为是错误的语法:
1JSON.parse('[1, 2, 3,]')
2// SyntaxError: JSON.parse: unexpected character at
3// line 1 column 10 of the JSON data
JSON 的确是在网页和 API 中传递信息的一种好格式,而且各种语言都有它的解析库,但但并不适合做配置文件。
.properties 和 INI
.properties 主要用在 JAVA 程序中,JAVA 内置对它的解析。它是一种简单的配置文件格式,规则大概只有下面几条:
- 使用
= :
或者空格作为键值对的分隔符; - 单引号和双引号会作为值的一部分;
- 允许使用
#
作为注释; - 可以使用
\
作为转义符,用来转义空格、换行和 Unicode 编码。
因为如此简单的格式,.properteis 基本上不需要进行任何解释就能直接使用。也正因为它如此简单,不支持层级关系,因此它并不能算做 好的配置文件 。
INI 则相当于扩展版本的 .properties ,包含 .properties 的所有优点,去除了一些缺点,并且可以使用 section 来支持层级。它与 .properties 的主要区别如下:
- 支持 [section];
- 不使用空格作为分隔符;
- 允许在键名和值中直接包含空格(不需使用转义符);
- 支持更多的转义符。
INI 格式是 好的配置文件 ,还包含 优秀的配置文件 的一些特性。由于解析简单,我们可以对它做一些扩展以符合我们的需求。
例如,我在 rookout 中对 ConfigParser 进行了一点点扩展,使得 ini 可以支持 [@list name]
这类特殊的 section ,将它们直接解析成 Python 中的 list。
XML 和 PLIST —— 虐心(也虐手)
XML 当然是 好的配置文件 ,但它编辑起来太麻烦。即使是有 XML Notepad 这类软件的存在,太多的尖括号和嵌套也让手写这种配置文件变得艰难。同样是由于太多的尖括号,让我不愿意阅读它。
PLIST 是 XML 的子集,是 Apple 定义的配置文件格式,在 Mac OS X 和 iOS 操作系统中得到大量的应用。PLIST 中直接包含类型信息,因此解析 PLIST 可以直接得到确定的数据类型(甚至是字典和数组)。 XCode 直接支持 PLIST 的编辑,但由于在 Apple 生态系统之外使用是在比较少,支持这种格式的编辑器和解析库都比较有限。当然你可以把它当作纯文本文件来编辑,那就又碰到了 XML 的问题。
我曾经用 ActionScript3 写过一个 PLIST 格式解析库,由于 AS3 对 XML 的原生支持,所以完成这个解析器还是很简单的工作。
同样,由于太多的尖括号,导致在版本管理中对不同的文件版本进行比较的时候并不太直观。
总之,我不愿意手写这两种配置文件格式,机器生成倒是很好的选择。
实际上,一些软件的特定文件格式就是基于 XML 的。例如 TexturePacker 的 tps 文件格式。
YAML —— 堪称完美
YAML: YAML Ain't Markup Language 是为了替代 XML 而生。它在 Ruby 中被发扬光大并为世人所知。下面摘抄一段关于 YAML 的评价,来自这里 :
为什么不是XML呢?因为:
- YAML的可读性好。
- YAML和脚本语言的交互性好。
- YAML使用实现语言的数据类型。
- YAML有一个一致的信息模型。
- YAML易于实现。
上面5条也就是XML不足的地方。同时,YAML也有XML的下列优点:
- YAML可以基于流来处理;
- YAML表达能力强,扩展性好。
总之,YAML试图用一种比XML更敏捷的方式,来完成XML所完成的任务。
YAML 完全达到我上面提到的 优秀配置文件 的标准,到目前为止,堪称完美。
(全文完)
- 文章ID:2360
- 原文作者:zrong
- 原文链接:https://blog.zengrong.net/post/configuration-files/
- 版权声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,非商业转载请注明出处(原文作者,原文链接),商业转载请联系作者获得授权。