yaml,json,ini這三種格式用來做配置文件,優缺點各在哪裡?

還有一種xml


適合人類編寫:ini &> toml &> yaml &> json &> xml &> plist

可以存儲的數據複雜度:xml &> yaml &> toml ~ json ~ plist &> ini


其實我覺得這三者,甚至包括xml,都不是很好的配置文件格式

在小一點的工程中,我可能會考慮yaml,但個人強烈推薦的一個配置文件格式就是HOCON(Human-Optimized Config Object Notation)

是由typesafe(開發scala和play framework的公司)主導的項目:

GitHub - typesafehub/config: Configuration library for JVM languages

在Google干過的同學可以參考GCL,會發現很多設計上的類似點。

我覺得比較完美的配置文件格式需有這些特性

  1. 語法要簡單,靈活

簡單大家都差不多

HOCON是JSON和java property的超集,最為靈活,你可以寫

a: {
b: {
c: 3
d: 4
}
}

也可以單獨寫

a.b.c=5

":"號也可以換成"="或者就完全省略

2. 能夠寫注釋,這點json簡直可悲,不過可以考慮加預處理的過程

3. 能夠比較方便的覆蓋參數值(方便書寫或者debug),比如說在config文件中定義了

a=1

可以在運行的時候,通過類似 program -Da=2或者a=2 program的的方式來覆蓋參數值,而不需要跑去修改配置文件本身

這一點HOCON完爆其他的幾種

4. 能夠重用配置片段,比較大一點的project中,經常有很多地方的配置需要保持一致,最好的辦法就是引入變數和引用的概念,比如可以類似

db_connection: {host: a, password: b, db_name: c, ..... }

service_a: {
host: yyy
db: $db_connection
}

service_b: {
host: yyy
db: $db_connection
}

這樣最大的好處是避免了copy and paste,在修改配置文件的時候能搞保證不出問題

這點yaml和hocon基本上都是做的不錯的,json沒有,ini我用的不多,好像是沒有。

yaml的實現其實比較簡單,就是單純的文本替換,這樣導致我要說的下一點被HOCON完爆。

5,可以繼承

這是HOCON完爆其他語言的地方。還是上面那個例子,假設service_b.db不僅僅是是要是用全局db_connection的值,要稍微修改其中host的值,可以

service_b: {
host: yyy
db: $db_connection {
host: abc
}
}

而且不需要重新copy and paste之前所有的內容

它的繼承非常強大,語義可以說基本上和普通OO語言沒有太大區別

另外HOCON可以包含文件,比如說你可以寫一個基礎的配置文件base.conf,然後再針對dev,staging和production分別做一份不同的文件,這樣可以很輕鬆地做到在不同的環境下,用不同的配置而且沒有重複的配置代碼,比如說

include "base.conf"

// 覆蓋默認值
db.connection = "product_machine:2000"
....

另外提一下twitter之前嘗試用scala語言本身來當config language,但是好像過於笨重


json的注釋不是標準, 大多數解析器不支持注釋

一個配置文件不加註釋是一種怎樣的體驗?

yaml的減號反人類啊, 每次打開unity3d的配置看, 真想把他們都刪掉

ini的標準其實蠻多的. 虛幻到現在都在用ini, 因為序列化快, 結構簡單. 與其用xml,還不如仿照虛幻做一個解析

推薦Protobuf以及其文本格式, 一次導出, 無需解析, 到處使用, 自帶反射..性能高, 爹是Google

廣告時間: GitHub - davyxu/tabtoy: 基於Protobuf的電子表格導出器

tabtoy就是基於純pb做配置來設計的,可以體驗下一鍵拿到數據開始寫邏輯的爽快感


如果用ini,還要自己擴充一些格式的話,那還不如直接用yaml。

很多時候,是一開始用ini,等以後需要複雜一點的時候,再轉換到yaml。


反正都是 S-Exp 的馬甲(逃


在 擴展性、人的可閱讀方面,相對於空間效率最高、解析開銷最低的 二進位結構格式,這些都比較好了。

我只從解析的複雜度來比較一下:

ini的結構是線性的,分析起來特別簡單、方便;

xml/json/yaml都是層次結構的,分析起來還是相當費勁——雖然都有現成的庫、類、函數幫程序員去分析了,但是它們的費勁仍然是程序運行的費勁,只是替程序員省掉了開發分析模塊的費勁而已。

公平起見,還要比較它們表達能力的強弱:

xml/json/yaml的層次結構的複雜,換來了表達能力強大的優點;

線性的ini,似乎表達能力弱一些,比如無法表達層次信息,

但是,其實也能表達複雜的層次結構的信息,只需在用法上做 小小的改進:把層次結構寫入key(obj1.field2.subobj4.field5=xxxx)

如果僅僅做配置文件,運行(解析)效率倒不是太重要,因為使用的不頻繁。

我倡導的以ini取代xml/json/yaml,是在內容表達協議上,因為這種用途,它們是被非常頻繁使用的,所以運行效率就不得不注重了。

利益相關:本人是 ini的鼓吹者和改進者,ini@http的創立者(soap是xml@http,就是覺得xml太複雜,所以改用ini取代)


一般配置文件有兩種。

一種是用來存儲程序運行過程中產生的一些配置的。或者程序本身有GUI進行配置,現在只是需要把這個結果存下來。

這種我一般用json。

原因是json支持層次和結構比較豐富(雖然不及xml,但也夠用了),而且各種語言json庫都不錯。

調試的時候也方便人類閱讀。編輯器自動格式化後可讀性就很好了,不像yaml需要一個遊標卡尺。

另外一種配置文件是需要人類閱讀和編寫的。比如命令行程序,因為很難通過GUI進行配置,一般都是通過一個可以有人類閱讀和編寫的配置文件進行配置的。

這種我一般用ini。

首先json不支持注釋,直接pass。這種情況下寫配置文件的人是你的用戶,在一個沒有注釋的配置文件里猜每個配置項啥意思或者要求對照文檔都不是很好的解決方案。

ini就很方便,就算你不知道ini是什麼,也能很快理解ini的結構並嘗試修改。

關於ini不能表示複雜數據結構的問題。

首先我用ini一般是給人類修改的配置文件用,這種配置文件需要存複雜的數據結構本身就不好,所以能通過修改程序本身避免的就會盡量避免。

實在避免不了的,尤其是有時候需要配置一個數組,我一般是在ini的配置值上寫json。(好在json的數組還比較容易讓人理解,舉例如下:

[main]
content_type=[2,3,5,7]

json大家都有好用的解析庫,ini就算沒有解析庫手寫一個也不是什麼難事。yaml就不一樣了,所以我感覺我除了python其他語言寫的程序很少用yaml。

xml?裝逼用(逃


json :最好用,結構清晰,容錯率高,使用工具軟體可以很方便的編寫和調試。

xml :這個就不是給人看的。

yml : yml嚴格的格式太反人類,容錯率太低。

ini : 靈活快速,結構性缺陷,只能用來存儲簡單配置,存儲複雜結構太繁瑣。

最後 : 配置文件是系統級變數,用來維護程序的可變參數,必須要結構清晰(因為不但程序讀取,也是給人看的),容錯率高(因為是人為去改動)。

還有關於注釋的個人看法 : 計算機編程語言是西方發明的,使用的是英語,在編程的概念中,變數,方法,類,這些的名稱的創建,通俗講就是起名應當是見名知意。其命名本身就包含了意義。

還有,我目前沒見過產品級軟體的配置文件寫注釋的,因為由於編碼原因注釋在不同條件下的展示並不是固定的。還有你的客戶可以是任何人,注釋你要用什麼語言去寫?如果是解決方案這樣的系統,如果需要用戶或維護人員去改動配置文件,一定會配備相關的手冊。所以注釋並不是配置文件最重要的問題。


json 的注釋可以是一個 "__comments" 這樣的屬性,缺點是不能折行

我喜歡這麼用

{

"attr1" : "val1",

"_oldAttr1": "removed"

}


為。。。為什麼沒有properties。。。


不裝逼玩fancy的話ini足以


歪個樓,CSS拿來做配置文件異常帶感:對層次化的配置滋磁很好,有sass和less這些預處理器可以用……缺點是似乎不滋磁數組……


推薦閱讀:

開源軟體的作者都不上班或者上班沒事做的嗎?
你人生中的第一個一萬行代碼是如何寫出的?
做主程序員是怎樣的體驗?
程序員大神都如何支配自己的薪水?
程序員轉行燒烤需要做哪些準備,有哪些優勢和劣勢?

TAG:程序員 | 優缺點 | JSON | 配置文件 |