go-ini入門教程


go-ini入門教程

go-ini簡介

Package ini provides INI file read and write functionality in Go.

在實際開發時,配置信息一般不會在代碼里硬編碼,通常是放在配置文件里,或者數據庫、緩存里。今天介紹的 go-ini 就是一個讀寫 ini文件的庫。

配置文件格式有很多,常用的有 jsonxmlini。其中 ini 是以節(section)和鍵(key)構成,如下所示:

#debug or release
RUN_MODE = debug

[app]
PAGE_SIZE = 10

快速使用

1、下載安裝

使用一個特定版本:

$ go get gopkg.in/ini.v1

使用最新版本:

$ go get github.com/go-ini/ini

如需更新請添加 -u 選項。

2、創建兩個文件(my.inimain.go),這里選擇放在 /home/ini-sample 目錄。

$ mkdir -p /home/ini-sample
$ cd /home/ini-sample
$ touch my.ini main.go
$ tree .
.
├── main.go
└── my.ini

0 directories, 2 files

3、編譯 my.ini 文件並輸入以下內容:

#debug or release
RUN_MODE = debug

[app]
PAGE_SIZE = 10

[server]
HTTP_PORT = 8000
READ_TIMEOUT = 60
WRITE_TIMEOUT = 60

[database]
TYPE = mysql
USER = 數據庫賬號
PASSWORD = 數據庫密碼
#127.0.0.1:3306
HOST = 數據庫IP:數據庫端口號
NAME = blog
TABLE_PREFIX = blog_

4、接着編寫 main.go 文件來操作剛才創建的配置文件。

package main
import (
    "fmt"
    "os"
    "gopkg.in/ini.v1"
)
func main() {
    cfg, err := ini.Load("my.ini")
    if err != nil {
        fmt.Printf("Fail to read file: %v", err)
        os.Exit(1)
    }
    // 典型讀取操作,默認分區可以使用空字符串表示
    fmt.Println("Run Mode:", cfg.Section("").Key("RUN_MODE").String())
    fmt.Println("Page Size:", cfg.Section("app").Key("PAGE_SIZE").String())
    // 試一試自動類型轉換
    fmt.Printf("Http Port: (%[1]T) %[1]d\n", cfg.Section("server").Key("HTTP_PORT").MustInt(9999))
    // 差不多了,修改某個值然后進行保存
    cfg.Section("").Key("RUN_MODE").SetValue("release")
    cfg.SaveTo("my.ini.local")
}

5、運行程序,可以看到以下輸出:

$ go run main.go
Run Mode: debug
Page Size: 10
Http Port: (int) 8000

$ cat my.ini.local 
# debug or release
RUN_MODE = release

[app]
PAGE_SIZE = 10

[server]
HTTP_PORT     = 8000
READ_TIMEOUT  = 60
WRITE_TIMEOUT = 60

[database]
TYPE         = mysql
USER         = 數據庫賬號
PASSWORD     = 數據庫密碼
# 127.0.0.1:3306
HOST         = 數據庫IP:數據庫端口號
NAME         = blog
TABLE_PREFIX = blog_

操作分區(Section)

獲取指定分區:

sec, err := cfg.GetSection("section name")

如果想要獲取默認分區,則可以用空字符串代替分區名:

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

操作鍵值(Value)

獲取一個類型為字符串(string)的值:

val := cfg.Section("").Key("key name").String()

Must*方法

當我們知道配置的鍵值是哪種格式時,可以使用 Must* 方法來獲取。

v = cfg.Section("").Key("BOOL").MustBool()
v = cfg.Section("").Key("FLOAT64").MustFloat64()
v = cfg.Section("").Key("INT").MustInt()
v = cfg.Section("").Key("INT64").MustInt64()
v = cfg.Section("").Key("UINT").MustUint()
v = cfg.Section("").Key("UINT64").MustUint64()
v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339)
v = cfg.Section("").Key("TIME").MustTime() // RFC3339
// 由 Must 開頭的方法名允許接收一個相同類型的參數來作為默認值,
// 當鍵不存在或者轉換失敗時,則會直接返回該默認值。
// 但是,MustString 方法必須傳遞一個默認值。
v = cfg.Section("").Key("String").MustString("default")
v = cfg.Section("").Key("BOOL").MustBool(true)
v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25)
v = cfg.Section("").Key("INT").MustInt(10)
v = cfg.Section("").Key("INT64").MustInt64(99)
v = cfg.Section("").Key("UINT").MustUint(3)
v = cfg.Section("").Key("UINT64").MustUint64(6)
v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now())
v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339

In*方法

獲取鍵值時設定候選值,可以使用 In* 方法:

v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"})
v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75})
v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30})
v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30})
v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9})
v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9})
v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3})
v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339

如果獲取到的值不是候選值的任意一個,則會返回默認值,而默認值不需要是候選值中的一員。

結構體與分區映射

有時候我們不想逐個獲取值,而是把分區內的值放到一個結構體里,以便使用。

配置文件:

#debug or release
RUN_MODE = debug

[app]
PAGE_SIZE = 10

[server]
HTTP_PORT = 8000
READ_TIMEOUT = 60
WRITE_TIMEOUT = 60

[database]
TYPE = mysql
USER = 數據庫賬號
PASSWORD = 數據庫密碼
#127.0.0.1:3306
HOST = 數據庫IP:數據庫端口號
NAME = blog
TABLE_PREFIX = blog_

代碼:

type Database struct {
	Type string
	User string
	Password string
	Host string
	Name string
	TablePrefix string
}

func Setup() {
	Cfg, err := ini.Load("conf/app.ini")
	if err != nil {
		log.Fatalf("Fail to parse 'conf/app.ini': %v", err)
	}

	err = Cfg.Section("database").MapTo(DatabaseSetting)
	if err != nil {
		log.Fatalf("Cfg.MapTo DatabaseSetting err: %v", err)
	}
}

使用心得

通常配置文件很少變更的,一般使用單例,在 go 里就是包內變量了,由於只需要讀取一次,所以一般會在 init 方法里讀取。

另外關於配置熱更新,可以查看這份文章:熱更新配置文件

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM