博客原文出处: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 提供很是全面,用法很是简单,但核心代码并很少,各位同窗有兴趣的能够阅读其源代码。