1. 程式人生 > >golang中goconfig包使用解析

golang中goconfig包使用解析

注意事項

本博文為 goconfig - Go 語言 INI 解析器的配套部落格,旨在通過文字結合程式碼示例對該庫的使用方法和案例進行講解,便於各位同學更好地使用和深入瞭解。

庫簡介

goconfig 是一個由 Go 語言開發的針對 Windows 下常見的 INI 格式的配置檔案解析器。該解析器在涵蓋了所有 INI 檔案操作的基礎上,又針對 Go 語言實際開發過程中遇到的一些需求進行了擴充套件。相對於其它 INI 檔案解析器而言,該解析器最大的優勢在於對註釋的極佳支援;除此之外,支援多個配置檔案覆蓋載入也是非常特別但好用的功能。

下載安裝

您可以通過以下兩種方式下載安裝 goconfig:

gopm get github.com/Unknwon/goconfig

go get github.com/Unknwon/goconfig

API 文件

基本使用方法

示例程式碼

一般來說,INI 格式的檔案均以 .ini 為字尾,但您可以使用任意字尾,這並不影響您使用該庫進行解析。在本例中,我們使用 conf.ini 作為我們的配置檔案。

載入配置檔案

要操作某個配置檔案,需要先將其載入到記憶體中,我們需要呼叫 LoadConfigFile 函式來完成該操作:

cfg, err := goconfig.LoadConfigFile("conf.ini")

配置檔案的檔名可以寫相對路徑或絕對路徑,該函式返回值分別為 ConfigFile

和 error 型別。如果載入操作發生錯誤,則變數 cfg 為 nil;否則 err 為 nil。載入完成之後,我們就可以通過操作變數 cfg 來對配置檔案的資料進行操作。要注意的是,載入完成後所有資料均已存入記憶體,任何對檔案的修改操作都不會影響到已經獲取到的物件。也就是說,此時對檔案的修改是不會影響到 cfg 這個物件裡的資料的。

基本讀寫操作

通過 GetValue 方法可實現最基本的讀取操作。在本例中,鍵 key_default 屬於未命名的分割槽(section),則 goconfig 在解析器將它直接歸於名為 DEFAULT 的分割槽。當我們想要獲取它的值的時候,可以進行如下操作:

value, err := cfg.GetValue(goconfig.DEFAULT_SECTION, "key_default")

第一個返回值為 string 型別,即取到的值;第二個返回值為 error 型別,當發生錯誤時不為 nil。

除了讀取之外,還可以進行設定值操作:

isInsert := cfg.SetValue(goconfig.DEFAULT_SECTION, "key_default", "這是新的值")

該方法返回值型別為 bool 型別,表示是否為插入操作。如果值為 true,表明該鍵之前未存在,現在插入成功;否則表示該鍵之前已經存在,它的值現在被重寫了。

如果您覺得每次都呼叫 goconfig.DEFAULT_SECTION 來表示 DEFAULT 分割槽非常繁瑣,您也可以直接使用空白字串來代表 DEFAULT 分割槽:

value, err = cfg.GetValue("", "key_default")

以上程式碼也可以達到相同的效果。

除了使用等號作為鍵值之間的分隔符之外,冒號也是允許的:

key_super2 : 測試值

註釋讀寫操作

雖然大多數情況下程式都只從 INI 檔案進行資料的讀取操作,但偶爾會需要實現寫入到檔案的操作。此時,其餘所有的解析器都會將註釋給過濾掉;當註釋是配置檔案各項說明的重要依據時,這種做法顯然是不可取的。因此,完整地儲存檔案中的註釋,並提供在程式中對註釋進行操作的 API 不可謂不是 goconfig 的一大特色。

goconfig 允許您的配置檔案以分號 ; 或井號 # 為開頭在單獨的一行作為註釋:

; 以分號開頭的均為註釋行
# 以井號開頭的也為註釋行

但不可以在某一行的中間:

key_default = 預設節的一個鍵 # 註釋必須單獨佔行,此處的註釋無效

通過 goconfig 提供的 API,您可以操作某個分割槽或鍵的註釋。

獲取某個分割槽的註釋:

comment := cfg.GetSectionComments("super")

獲取某個鍵的註釋:

comment = cfg.GetKeyComments("super", "key_super")

這兩個方法均返回 string 型別的返回值。

設定某個鍵的註釋:

v := cfg.SetKeyComments("super", "key_super", "# 這是新的鍵註釋")

設定某個分割槽的註釋:

v = cfg.SetSectionComments("super", "# 這是新的分割槽註釋")

上面兩個方法的返回值都是 bool 型別。若為 true 表示註釋被插入或刪除(當傳入的引數為空字串時);為 false 表示註釋已存在,現在被重寫。

型別轉換讀取

goconfig 提供以型別命名的一些方法,例如 IntInt64Bool 等等,這些方法會返回非 string 型別的值以及一個 error 型別的返回值表示是否發生錯誤:

vInt, err := cfg.Int("must", "int")

第一個返回值為 int 型別,第二個返回值為 error 型別。

Must 系列方法

Must 系列方法是用於避免檢查 error 型別所造成的程式碼臃腫,簡化資料獲取流程。這些方法均已 Must 字元開頭,如 MustIntMustInt64MustBool 等等。這些方法一定會返回指定型別的值,若發生錯誤,則返回零值,不會發生錯誤:

vBool := cfg.MustBool("must", "bool")

該方法返回值為 bool 型別。

刪除指定鍵值

當您想要拋棄某個鍵時,可以通過 DeleteKey 方法來刪除某個鍵:

ok := cfg.DeleteKey("must", "string")

該方法返回值為 bool 型別,用於表示刪除操作是否成功(若鍵不存在則會表示為不成功)。

儲存配置檔案

當完成操作需要將資料寫回硬碟時,可以使用 SaveConfigFile 函式來將 ConfigFile 物件以字串的形式儲存到檔案系統中:

err = goconfig.SaveConfigFile(cfg, "conf_save.ini")

您需要指定要儲存的物件和檔名,該方法返回一個 error 型別的值。

高階使用技巧

示例程式碼

上一小結展示瞭如果使用 goconfig 完成常見的 INI 檔案操作,本小節則將著重介紹 goconfig 庫為大家帶來的一些擴充套件功能。

多檔案覆蓋載入

函式 LoadConfigFile 其實可以接受多個 string 型別的引數來表示要載入的多個配置檔名,並根據次序進行覆蓋式地載入:

cfg, err := goconfig.LoadConfigFile("conf.ini", "conf2.ini")

在本例中,如果 conf.iniconf2.ini 中同時出現相同分割槽和鍵名時,則只會獲取到 conf2.ini 檔案中的值。

如果在程式執行途中發現需要增加配置檔案,則可通過方法 AppendFiles 實現追加操作:

err = cfg.AppendFiles("conf3.ini")

配置檔案過載

若外部檔案發生修改,可通過呼叫方法進行快速過載:

err = cfg.Reload()

該方法返回一個 error 型別的值表示操作是否成功。

為 Must 系列方法設定預設值

藉助 Go 語言變參的功能,當 Must 系列方法擁有三個引數時,則第三個引數即為獲取失敗時的預設值:

vBool := cfg.MustBool("must", "bool404", true)

本例中鍵名為 bool404 根本不存在,則會採用 true 作為返回值。

遞迴讀取鍵值

在檔案 conf3.ini 中,預設分割槽有兩個鍵如下:

google=www.google.com
search=http://%(google)s

當您使用 %(<key>)s 包含某個鍵名來作為值的時候,goconfig 會去尋找相應的鍵的值進行替換;如果被替換的鍵的值還有這樣的巢狀,則會遞迴執行替換。該操作最多允許 200 層的巢狀。此時,鍵 search 真正的值為 。要注意的是,被包含的鍵可以是位於 DEFAULT 分割槽或同一分割槽的,出現順序任意。

子孫分割槽覆蓋讀取

在檔案 conf3.ini 中,有如下配置:

[parent]
name=john
relation=father
sex=male
age=32

[parent.child]
age=3

當我們獲取 parent.child 分割槽中的鍵 age 時,我們會得到 3;但當我們想要獲取 sex 時,正常情況下應該為獲取失敗,不過,goconfig 會發現 parent.child 還有父分割槽 parent,因為 parent.child 使用了半形符號 . 來實現分級。這時候,獲取 sex 會得到 male

自增鍵名獲取

在檔案 conf3.ini 中,有如下配置:

[auto increment]
-=hello
-=go
-=config

由於使用 - 作為鍵名,則 goconfig 在解析時,會將它翻譯成自增數字,從 1 開始。在本例中,上面的鍵在物件中會被儲存為:

#1: hello
#2: go
#3: config

要注意的是,計數只在同個分割槽內有效,新的分割槽又會從 1 開始重新計數。

獲取整個分割槽

如果您想要直接操作某個分割槽,可通過方法 GetSection 來返回一個型別為 map[string]string 的值,其包含了相應分割槽的所有鍵值對:

sec, err := cfg.GetSection("auto increment")

總結

goconfig 包的 API 提供非常全面,用法非常簡單,但核心程式碼並不多,各位同學有興趣的可以閱讀其原始碼。

使用案例