博客原文出處:http://wuwen.org/article/17/01-goconfig-class1.htmlhtml
注意事項nginx
本博客隸屬於 goconfig - 課時 1:goconfig 使用解析 請注意配套使用。git
本博文爲 goconfig - Go 語言 INI 解析器的配套博客,旨在經過文字結合代碼示例對該庫的使用方法和案例進行講解,便於各位同窗更好地使用和深刻了解。github
goconfig 是一個由 Go 語言開發的針對 Windows 下常見的 INI 格式的配置文件解析器。該解析器在涵蓋了全部 INI 文件操做的基礎上,又針對 Go 語言實際開發過程當中遇到的一些需求進行了擴展。相對於其它 INI 文件解析器而言,該解析器最大的優點在於對註釋的極佳支持;除此以外,支持多個配置文件覆蓋加載也是很是特別但好用的功能。sql
您能夠經過如下兩種方式下載安裝 goconfig:ubuntu
gopm get github.com/Unknwon/goconfig
或bash
go get github.com/Unknwon/goconfig
請移步 Go Walker。ide
示例代碼函數
通常來講,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 提供以類型命名的一些方法,例如 Int
、Int64
和 Bool
等等,這些方法會返回非 string 類型的值以及一個 error 類型的返回值表示是否發生錯誤:
vInt, err := cfg.Int("must", "int")
第一個返回值爲 int 類型,第二個返回值爲 error 類型。
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 類型的值表示操做是否成功。
藉助 Go 語言變參的功能,當 Must 系列方法擁有三個參數時,則第三個參數即爲獲取失敗時的默認值:
vBool := cfg.MustBool("must", "bool404", true)
本例中鍵名爲 bool404
根本不存在,則會採用 true 做爲返回值。
在文件 conf3.ini
中,默認分區有兩個鍵以下:
google=www.google.comsearch=http://%(google)s
當您使用 %(<key>)s
包含某個鍵名來做爲值的時候,goconfig 會去尋找相應的鍵的值進行替換;若是被替換的鍵的值還有這樣的嵌套,則會遞歸執行替換。該操做最多容許 200 層的嵌套。此時,鍵 search
真正的值爲 http://%(www.google.com)s
。要注意的是,被包含的鍵必須是已經出現的,若是將上面兩行文本對換位置,則就達不到咱們的預期效果。
在文件 conf3.ini
中,有以下配置:
[parent]name=johnrelation=fathersex=maleage=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 提供很是全面,用法很是簡單,但核心代碼並很少,各位同窗有興趣的能夠閱讀其源代碼。