淺談配置文件格式
流行的配置文件格式有若干種,每種都有其自身優勢。從中找到最適合你的格式吧!
計算機上有數以千計的配置文件。你可能永遠不會直接與其中的大部分文件打交道,但它們確實散落在你的 /etc 以及 ~/.config、~/.local、/usr 文件夾中。還有一些可能在 /var,甚至 /opt 文件夾中。如果無意中打開過或更改過它們,你就可能會有疑問:為什么有些配置文件看起來是某一種格式,而另一些則是看起來完全不同的格式?
存儲配置是一項很靈活的任務,因為只要開發人員知道他們的代碼是如何將數據存入文件的,他們就可以輕松編寫代碼來根據需要提取數據。然而,科技行業非常青睞有詳細文檔的標準化事物,因此多年來出現了幾種比較普遍的格式用來簡化配置任務。
為什么我們需要配置文件
配置文件對于現代計算來說很重要。它們使你能夠自定義與應用程序交互的方式,或自定義應用程序與系統內其他程序的交互方式。有了配置文件,每當你啟動某個應用程序時,它都會有“記憶”,記錄了你喜歡如何去使用該程序。
配置文件的結構可以很簡單,而且通常確實也很簡單。例如,如果你要編寫一個應用程序,程序唯一需要知道的是其用戶的偏好名字,那么它的唯一配置文件就可以只包含一個詞:用戶名。就像下面這樣:
- Tux
但通常應用程序需要追蹤的不僅僅是一條信息,因此配置文件通常會有一個鍵和一個值:
- NAME='Tux'
- SPECIES='Penguin'
即使沒有編程經驗,你也可以想象出代碼如何解析這些數據。這里有兩個簡單的例子,一個使用 awk 命令,另一個使用 grep 命令。兩個例子都是只關注包含 NAME “鍵”的行,并返回出現在等號 (=) 之后的“值”:
- $ awk -F'=' '/NAME/ { print $2; }' myconfig.ini
- 'Tux'
- $ grep NAME fake.txt | cut -d'=' -f2
- 'Tux'
同樣的原則適用于任何編程語言和任何配置文件。只要你有統一的數據結構,就可以在需要的時候編寫簡單的代碼來提取和解析它。
選擇格式
為了保證普遍有效性,配置文件最重要的一點是它們是一致的和可預測的。你絕對不會想做這樣的事:以保存用戶首選項的名義,將信息隨意存儲到文件中,然后花好幾天時間逆向工程,來找到最終出現在文件中的隨機信息。
流行的配置文件格式有若干種,每種格式都有自己的優勢。
INI
INI 文件采用了鍵值對的格式:
- [example]
- name=Tux
- style=widgety,fidgety
- enabled=1
這種簡單的配置風格很直觀,只要你別選擇使用糟糕的鍵名(比如用 unampref 這樣的神秘鍵名來代替 name)就好。這些鍵值對很容易解析和編輯。
除了鍵和值之外,INI 格式還可以分 節section。在下列示例代碼中,[example] 和 [demo] 就是配置文件中的兩個節:
- [example]
- name=Tux
- style=widgety,fidgety
- enabled=1
- [demo]
- name=Beastie
- fullscreen=1
這幾個配置語句解析起來有點復雜,因為有兩個 name 鍵。想象一下,一個粗心的程序員在這個配置文件中查詢 name,結果總是返回 Beastie,因為這是文件中對 name 的最后一個定義值。在解析這樣的文件時,開發人員必須加倍小心地在各節中搜索鍵,這可能會很棘手,具體取決于用來解析該文件的語言。然而,它仍然是一種很流行的格式,大多數語言都會有一個現成的庫來幫助程序員解析 INI 文件。
YAML
YAML 文件 是結構化列表,可以包含值或者鍵值對:
- ---
- Example:
- Name: 'Tux'
- Style:
- - 'widgety'
- - 'fidgety'
- Enabled: 1
YAML 格式很流行,部分原因是它看起來很整潔。數據要放置到相對其上層數據的特定位置,除此之外沒有太多其他語法。然而,對于某些人來說的這種特色,在其他人眼中可能就是一個問題。許多開發人員不愿使用 YAML,正是因為它很看重本質上 不存在 的東西。如果你在 YAML 中縮進錯誤,YAML 解析器可能會將你的文件視為無效文件,即使不視為無效,返回的數據也可能是錯誤的。
大多數語言都有 YAML 解析器,并且有很好的開源 YAML linters(驗證語法的應用程序)來幫你確保 YAML 文件的完整性。
JSON
JSON 文件在技術上來說是 YAML 的子集,因此其數據結構是相同的,盡管其語法完全不同:
- {
- "Example": {
- "Name": [
- "Tux"
- ],
- "Style": [
- "widgety",
- "fidgety"
- ],
- "Enabled": 1
- }
- }
JSON 在 JavaScript 程序員中很流行,這并不奇怪,因為 JSON 全稱為JavaScript 對象符號JavaScript Object Notation。由于與 Web 開發密切相關,JSON 是 Web API 的常見輸出格式。大多數編程語言都有解析 JSON 的庫。
XML
XML 使用標簽作為鍵,將配置值圍繞起來:
- <example>
- <name>Tux</name>
- <style priority="user">widgety</style>
- <style priority="fallback">fidgety</style>
- <enabled>1</enabled>
- </example>
XML 經常被 Java 程序員使用,Java 有一套豐富的 XML 解析器。雖然 XML 以非常嚴格而著稱,但同時也非常靈活。與有一系列特定標簽的 HTML 不同,XML 中可以隨意發明自己的標簽。只要始終堅持相同的構建規則,并有一個良好的庫來解析它,你就可以準確而輕松地提取數據。
有一些很好的開源 linter 可以幫你驗證 XML 文件,并且大多數編程語言都提供用于解析 XML 的庫。
二進制格式
Linux 以純文本配置為傲。這樣做的優點是可以使用 cat 等基本工具查看配置數據,甚至可以使用你 最喜歡的文本編輯器 來編輯配置。
但是,某些應用程序使用二進制格式配置,就意味著數據以某種非自然語言的格式進行編碼。這些文件通常需要一個特殊的應用程序(通常是它們要配置的應用程序)來解釋它們的數據。你無法查看這些文件,至少無法以任何有意義的方式查看,并且無法在其宿主應用程序之外編輯它們。選用二進制格式的一些原因如下:
- 速度: 程序員可以使用自定義符號在二進制配置文件中的某些點注冊特定的信息位。提取數據時不涉及搜索,因為所有內容都已標注了索引。
- 大小: 文本文件可能會變大,如果選擇壓縮文本文件,實際上是在將其轉換為二進制格式。二進制文件可以通過編碼技巧變得更小(文本文件也是如此,但在某些時候,你的優化會使數據變得晦澀,以至于文件也成了二進制文件)。
- 晦澀: 一些程序員甚至不希望人們查看他們的配置文件,因此將它們編碼為二進制數據。這通常只會讓用戶感到沮喪,并不是使用二進制格式的好理由。
如果必須使用二進制格式進行配置,請使用已作為開放標準存在的格式,例如 NetCDF。
找到有效的配置格式
配置格式幫助開發人員存儲應用程序所需的數據,并幫助用戶存儲他們希望應用程序如何操作的偏好項。對于應該使用什么格式的問題,可能沒有錯誤的答案,只要你覺得所使用的語言能很好地支持就可以。在開發應用程序時,查看可用格式,用一些樣例數據建模,查看和評估你的編程語言提供的庫和實用程序,然后選擇你覺得最合適的一種格式吧。