掌握Go语言:INI文件的配置与管理

发表时间: 2019-09-24 15:33

第三方库

gopkg.in/ini.v1


配置加载

创建一个空的配置

cfg := ini.Empty()

直接加载存在的配置文件,如果文件不存在就会报错

cfg, err := ini.Load("app.ini")

可以同时加载多个配置文件,后面的配置文件键值会覆盖前面一个

cfg, err := ini.Load("app.ini", "app_dev.ini")

不能够确定其中哪些文件是不存在的,可以通过调用函数 LooseLoad() 来忽略它们。

cfg, err := ini.LooseLoad("app.ini", "app_dev.ini")

跳过无法识别的数据行

cfg, err := ini.LoadSources(ini.LoadOptions{SkipUnrecognizableLines: true}, "other.ini")


保存配置

比较原始的做法是输出配置到某个文件:

err = cfg.SaveTo("app.ini")

保存时调整缩进

err = cfg.SaveToIndent("app.ini", "\t")


操作分区

获取制定分区的对象

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

如果想要获取默认分区,则可以用空字符串代替分区名:

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

相对应的,还可以使用 ini.DEFAULT_SECTION 来获取默认分区:

sec, err := cfg.GetSection(ini.DEFAULT_SECTION)

当您非常确定某个分区是存在的,可以使用以下简便方法:

sec := cfg.Section("section name")

如果不存再,会自动创建并返回一个对应的分区对象。

创建一个分区:

err := cfg.NewSection("new section")

获取所有分区对象或名称:

secs := cfg.Sections()names := cfg.SectionStrings()


操作键

key, err := cfg.Section("").GetKey("key name")

和分区一样,您也可以直接获取键而忽略错误处理:

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

判断某个键是否存在:

yes := cfg.Section("").HasKey("key name")

创建一个新的键:

err := cfg.Section("").NewKey("name", "value")

获取分区下的所有键或键名:

keys := cfg.Section("").Keys()names := cfg.Section("").KeyStrings()

获取分区下的所有键值对的克隆:

hash := cfg.Section("").KeysHash()

操作键值

获取一个类型为字符串(string)的值:

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

获取值的同时通过自定义函数进行处理验证:

val := cfg.Section("").Key("key name").Validate(func(in string) string { if len(in) == 0 { return "default" } return in})

如果不需要任何对值的自动转变功能(例如递归读取),可以直接获取原值(这种方式性能最佳):

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

判断某个原值是否存在:

yes := cfg.Section("").HasValue("test value")

获取其它类型的值:

// 布尔值的规则:// true 当值为:1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On// false 当值为:0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Offv, err = cfg.Section("").Key("BOOL").Bool()v, err = cfg.Section("").Key("FLOAT64").Float64()v, err = cfg.Section("").Key("INT").Int()v, err = cfg.Section("").Key("INT64").Int64()v, err = cfg.Section("").Key("UINT").Uint()v, err = cfg.Section("").Key("UINT64").Uint64()v, err = cfg.Section("").Key("TIME").TimeFormat(time.RFC3339)v, err = cfg.Section("").Key("TIME").Time() // RFC3339v = 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

操作注释

下述几种情况的内容将被视为注释:

所有以 # 或 ; 开头的行

所有在 # 或 ; 之后的内容

分区标签后的文字 (即 [分区名] 之后的内容)

如果你希望使用包含 # 或 ; 的值,请使用 ` 或 """ 进行包覆。

除此之外,还可以通过 LoadOptions 完全忽略行内注释:

cfg, err := ini.LoadSources(ini.LoadOptions{ IgnoreInlineComment: true,}, "app.ini")

或要求注释符号前必须带有一个空格:

cfg, err := ini.LoadSources(ini.LoadOptions{ SpaceBeforeInlineComment: true,}, "app.ini")