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
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 提供以型別命名的一些方法,例如 Int
、Int64
和 Bool
等等,這些方法會返回非 string 型別的值以及一個 error 型別的返回值表示是否發生錯誤:
vInt, err := cfg.Int("must", "int")
第一個返回值為 int 型別,第二個返回值為 error 型別。
Must 系列方法
Must 系列方法是用於避免檢查 error 型別所造成的程式碼臃腫,簡化資料獲取流程。這些方法均已 Must
字元開頭,如
MustInt
、MustInt64
和 MustBool
等等。這些方法一定會返回指定型別的值,若發生錯誤,則返回零值,不會發生錯誤:
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.ini
和 conf2.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 提供非常全面,用法非常簡單,但核心程式碼並不多,各位同學有興趣的可以閱讀其原始碼。