Go语言中INI配置文件格式解析
程序员文章站
2022-07-09 19:09:20
init配置文件与解析 INI配置文件有三要素 1. parameters 指一条配置,就像key = value这样的。 2. sections sections是parameters的集合,sections必须独占一行并且用[]括起来。 sections没有明显的结束方式,一个sections的 ......
init配置文件与解析
ini配置文件有三要素
- parameters
指一条配置,就像key = value这样的。
- sections
sections是parameters的集合,sections必须独占一行并且用[]括起来。
sections没有明显的结束方式,一个sections的开始就是另一个sections的结束。
- comments
指ini配置文件的注释,以 ; 开头。
[database] serverip=********** serverport=8080 controlconnectstring=qwdj7+xh6owaanaghvgh5/5uxyra2rfz/ufakdln1h9tw+v7z0socfr+wydyzcjf/anufpxlo6cldahm4xxmbadyks6zmkwugqngdzmpx6c= controlconnectcategory=0 [logoninfo] saveuserid=y userid=admin dbserver=appdb dbcenter=demo [userconfig] opendownloadfileatonec=y windowstyle=devexpress dark style [language] language=chs [autoupdate] version=1.1
init 配置文件的解析
这里我们使用github上的第三方库(https://github.com/go-ini)
。
**package ini provides ini file read and write functionality in go. **
安装
the minimum requirement of go is 1.6.
$ go get gopkg.in/ini.v1
please add -u
flag to update in the future.
开始使用
我们将通过一个非常简单的例子来了解如何使用。
首先,我们需要在任意目录创建两个文件(my.ini
和 main.go
),在这里我们选择 /tmp/ini
目录。
$ mkdir -p /tmp/ini $ cd /tmp/ini $ touch my.ini main.go $ tree . . ├── main.go └── my.ini 0 directories, 2 files
现在,我们编辑 my.ini
文件并输入以下内容(部分内容来自 grafana)。
# possible values : production, development app_mode = development [paths] # path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) data = /home/git/grafana [server] # protocol (http or https) protocol = http # the http port to use http_port = 9999 # redirect to correct domain if host header does not match domain # prevents dns rebinding attacks enforce_domain = true
很好,接下来我们需要编写 main.go
文件来操作刚才创建的配置文件。
package main import ( "fmt" "os" "gopkg.in/ini.v1" ) func main() { cfg, err := ini.load("my.ini")//初始化一个cfg if err != nil { fmt.printf("fail to read file: %v", err) os.exit(1) } // 典型读取操作,默认分区可以使用空字符串表示 fmt.println("app mode:", cfg.section("").key("app_mode").string()) fmt.println("data path:", cfg.section("paths").key("data").string()) // 我们可以做一些候选值限制的操作 fmt.println("server protocol:", cfg.section("server").key("protocol").in("http", []string{"http", "https"})) // 如果读取的值不在候选列表内,则会回退使用提供的默认值 fmt.println("email protocol:", cfg.section("server").key("protocol").in("smtp", []string{"imap", "smtp"})) // 试一试自动类型转换 fmt.printf("port number: (%[1]t) %[1]d\n", cfg.section("server").key("http_port").mustint(9999)) fmt.printf("enforce domain: (%[1]t) %[1]v\n", cfg.section("server").key("enforce_domain").mustbool(false)) // 差不多了,修改某个值然后进行保存 cfg.section("").key("app_mode").setvalue("production") cfg.saveto("my.ini.local") }
运行程序,我们可以看下以下输出
$ go run main.go app mode: development data path: /home/git/grafana server protocol: http email protocol: smtp port number: (int) 9999 enforce domain: (bool) true $ cat my.ini.local # possible values : production, development app_mode = production [paths] # path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) data = /home/git/grafana ...
高级用法
将配制文件映射到结构体
想要使用更加面向对象的方式玩转 ini 吗?好主意。
配置文件如下:
name = unknwon age = 21 male = true born = 1993-01-01t20:17:05z [note] content = hi is a good man! cities = hangzhou, boston
//按照配置文件的内容构造结构体 type note struct { content string cities []string } type person struct { name string age int `ini:"age"`//这里需要用到反射,因为和ini文件的字段不同 male bool born time.time note created time.time `ini:"-"` } func main() { cfg, err := ini.load("path/to/ini") // ... p := new(person)//初始化一个结构体,返回指向他的指针 err = cfg.mapto(p) // ... // 一切竟可以如此的简单。 err = ini.mapto(p, "path/to/ini")//核心代码 // ... // 嗯哼?只需要映射一个分区吗? n := new(note) err = cfg.section("note").mapto(n) // ... }
结构的字段怎么设置默认值呢?很简单,只要在映射之前对指定字段进行赋值就可以了。如果键未找到或者类型错误,该值不会发生改变。
// ... p := &person{ name: "joe", } // ..
将结构体映射成配置文件
type embeded struct { dates []time.time `delim:"|" comment:"time data"` places []string `ini:"places,omitempty"` none []int `ini:",omitempty"` } type author struct { name string `ini:"name"` male bool age int `comment:"author's age"` gpa float64 nevermind string `ini:"-"` *embeded `comment:"embeded section"` } func main() { a := &author{"unknwon", true, 21, 2.8, "", &embeded{ []time.time{time.now(), time.now()}, []string{"hangzhou", "boston"}, []int{}, }} cfg := ini.empty()//初始化一个空配置文件 err = ini.reflectfrom(cfg, a)//核心代码 // ... }
瞧瞧,奇迹发生了。
name = unknwon male = true ; author's age age = 21 gpa = 2.8 ; embeded section [embeded] ; time data dates = 2015-08-07t22:14:22+08:00|2015-08-07t22:14:22+08:00 places = hangzhou,boston
参考文献:
上一篇: Python 抓取动态网页表格信息