Golang实践录:读取toml配置
2023-12-13 04:27:26
本文对 toml 文件进行解析。
下载
对于toml格式文件,golang 有很多库可以解释 yaml 文件,如toml、viper。由于 viper 可解析格式较多,本文采用该库。
toml语法规则
toml语法规则在官方中文文档上有说明,这里直接使用。
- TOML 是大小写敏感的。
- TOML 文件必须是合法的 UTF-8 编码的 Unicode 文档。
- 空白是指制表符(0x09)或空格(0x20)。
- 换行是指 LF(0x0A)或 CRLF(0x0D 0x0A)
测试
yaml 配置文件
# toml 测试样例
# 文件格式必须为utf8
# 名称
# 字符串
name = "conf file"
# 版本
# 如按浮点,2.0会转换成2
# 如按字符串,保留原样
version = "2.0"
# 布尔类,转换为true或false
need = true
# 时间 注:如果加双引号,就变成字符串了
time = 2020-10-03T09:21:13Z
#time = 2020-10-03T09:21:13-08:00
empty = "empty"
# 多行
text = '''
hello
world!
'''
# 简单的数组
fruit = [
"apple",
"apple1",
"apple2",
"apple3",
"apple4",
"apple5",
]
ports = [8080, 8081, 8082,]
# 多层级
loginfo.log.dir = "log"
## 前面是顶层表 下面是类似ini节的概念
######
#节或表,后必须再跟 [],如果不加,即使顶格,也被认为在该节名下
#
# \n会被识别
[my]
name = "late \n lee"
#name1 = "late \n lee"
age = 99
# 多级数组
[multi]
sta = [
"jim kent jk@latelee.org",
"late lee li@latelee.org",
"foo foo@latelee.org",
]
# 多级对象
[mymap]
dir = "mymap"
[[mymap.map_data]]
name = "在线"
attri = "在线电子"
url = "http://abc.com"
[[mymap.map_data]]
name = "离线"
attri = "离线电子"
url = "http://ccc.com"
# more
该示例基本涵盖了大部分的 yaml 格式。包括:字符串,数值、数组、多级map。
测试代码
测试代码如下:
package test
import (
"fmt"
"testing"
"github.com/spf13/viper"
)
var (
cfgFile string // = "config.toml"
)
type mapUrl_t struct {
Name string `json:"name"`
Attri string `json:"attri"`
Url string `json:"url"`
}
func TestToml(t *testing.T) {
fmt.Println("test of toml...")
// 设置配置文件的2种方式
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
viper.AddConfigPath("./")
viper.SetConfigName("config")
viper.SetConfigType("toml")
}
// 读取 注:如果toml格式有误,此处报错
err := viper.ReadInConfig()
if err != nil {
fmt.Printf("'%v' file read error: %v\n", cfgFile, err)
return
}
name := viper.GetString("name") // 读取 字符串
version := viper.GetString("version")
need := viper.GetBool("need") // 读取 布尔
theTime := viper.GetString("time")
empty := viper.GetString("empty")
text := viper.GetString("text")
fmt.Printf("need: %v name: %v\nversion: %v \ntime: %v \nempty: %s \ntext: %v\n", need, name, version, theTime, empty, text)
// 多级读取
name = viper.GetString("my.name")
name1 := viper.GetString("my.name1")
age := viper.GetInt("my.age")
fmt.Printf("name: %v, name1: %v age: %v \n", name, name1, age)
// 字符串数组
newSta := viper.GetStringSlice("multi.sta")
for idx, value := range newSta {
fmt.Printf("sta[%d]: %v\n", idx, value)
}
fruit := viper.GetStringSlice("fruit")
fmt.Printf("fruit: %v\n", fruit)
ports := viper.GetIntSlice("ports")
fmt.Printf("ports: %v\n", ports)
// 读取不存在的字段,字符串为空,数值为0
bad := viper.GetString("bad")
bad1 := viper.GetInt("my.bad")
fmt.Printf("bad: [%v] bad1: [%v]\n", bad, bad1)
logdir := viper.GetString("loginfo.log.dir")
fmt.Printf("logdir: %v\n", logdir)
// 多级对象
// tmpMap := make([]mapUrl_t, 0, 20)
var tmpMap []mapUrl_t
viper.UnmarshalKey("mymap.map_data", &tmpMap)
for _, item := range tmpMap {
fmt.Printf("name: %v url: %v\n", item.Name, item.Url)
}
// viper.WatchConfig()
// viper.OnConfigChange(func(e fsnotify.Event) {
// fmt.Println("配置发生变更:", e.Name)
// })
}
测试命令:
go test -v -run TestYaml
测试结果:
test of toml...
need: true name: conf file
version: 2.0
time: 2020-10-03 09:21:13 +0000 UTC
empty: empty
text: hello
world!
name: late
lee, name1: age: 99
sta[0]: jim kent jk@latelee.org
sta[1]: late lee li@latelee.org
sta[2]: foo foo@latelee.org
fruit: [apple apple1 apple2 apple3 apple4 apple5]
ports: [8080 8081 8082]
bad: [] bad1: [0]
logdir: log
name: 在线 url: http://abc.com
name: 离线 url: http://ccc.com
结果说明
1、由于使用的是viper解析,除了配置文件不同外,API接口及用法和解析yaml保持一致。
2、参数的值不能为 null 或 NULL,但可以为nul。如果为 null,解析的值为空。
3、如果字段不存在,不会报错,按字符串解析得到的值为空,如用数值,值为0。
4、对于多层级的对象,可以用viper.UnmarshalKey
,用法与解析json、yaml类似。
文章来源:https://blog.csdn.net/subfate/article/details/134833330
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!