乐趣区

关于go:使用viper解析ini配置文件

在我的项目中,常常应用 ini 和 yaml 作为配置文件。

对于 ini 配置文件,始终应用 https://github.com/go-ini/ini 这个库来解析配置。次要是因为简略易用并且中文文档反对较好。

对于 viper,之前是不反对 ini 配置的,对于 viper 为什么不反对 ini,官网 QA 有一段解释

Q: Why not INI files?

A: Ini files are pretty awful. There’s no standard format, and they are hard to validate. Viper is designed to work with JSON, TOML or YAML files. If someone really wants to add this feature, I’d be happy to merge it. It’s easy to specify which formats your application will permit.

看来 ini 格局始终不受 viper 待见 …

最近翻看 viper 文档的时候,发现在 v1.6.0 的版本中曾经增加了对 ini 的反对,大略体验了下。

轻易找了一个 ini 配置文件

# 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
// 指定要解析的配置文件
viper.SetConfigFile("my.ini")
if err := viper.ReadInConfig(); err != nil {log.Fatal(err)
}
// 默认 section 为 default
fmt.Printf("app_mode:%v\n", viper.GetString(`default.app_mode`))
fmt.Printf("server.protocol:%v\n", viper.GetString(`server.protocol`))

// 获取所有配置
all := viper.AllSettings()
fmt.Printf("%#v\n", all)

// 解析 section 到 struct
server := struct {
  Protocol      string `mapstructure:"protocol"`
  HttpPort      int    `mapstructure:"http_port"`
  EnforceDomain bool   `mapstructure:"enforce_domain"`
}{}
if err := viper.UnmarshalKey("server", &server); err != nil {fmt.Println("ini 解析到 struct 异样:", err)
} else {fmt.Println("struct:", server)
}

输入

app_mode:development
server.protocol:http
map[string]interface {}{"default":map[string]interface {}{"app_mode":"development"}, "paths":map[string]interface {}{"data":"/home/git/grafana"}, "server":map[string]interface {}{"enforce_domain":"true", "http_port":"9999", "protocol":"http"}}
struct:  {http 9999 true}

能够看出,对于一些罕用的性能应用起来也是比较简单不便的。

viper 中提供如下办法来获取配置

  • Get(key string) : interface{}
  • GetBool(key string) : bool
  • GetFloat64(key string) : float64
  • GetInt(key string) : int
  • GetIntSlice(key string) : []int
  • GetString(key string) : string
  • GetStringMap(key string) : map[string]interface{}
  • GetStringMapString(key string) : map[string]string
  • GetStringSlice(key string) : []string
  • GetTime(key string) : time.Time
  • GetDuration(key string) : time.Duration
  • IsSet(key string) : bool
  • AllSettings() : map[string]interface{}

参考

https://github.com/spf13/viper

退出移动版