golang实现INI文件解析与结构体映射的插件库ini的使用
Golang实现INI文件解析与结构体映射的插件库ini的使用
介绍
INI解析器和读写库是一个快速且易于使用的库,用于在Go编程语言中解析和操作INI文件。它提供了从字节切片和文件读取INI文件的功能,支持实时文件监控,并提供将INI数据解组到Go结构体、将数据编组为JSON以及将数据写回文件的选项。
特性
- 通过[]byte读取:允许解析存储在字节切片中的INI数据
- 通过文件读取:可以直接从文件读取INI数据
- 实时文件监控:支持文件监控,无需手动重新加载即可观察INI文件的变化
- 解组到结构体:可以将INI数据映射到Go结构体,方便处理结构化数据
- 编组为JSON:可以轻松将INI数据转换为JSON格式
- 写入文件:可以将INI数据写回文件,保留原始文件格式
安装
go get github.com/wlevene/ini
示例
基本使用
import (
"fmt"
"github.com/wlevene/ini"
)
func main() {
doc := `
[section]
k=v
[section1]
k1=v1
k2=1
k3=3.5
k4=0.0.0.0
`
// 获取值
v1 := ini.New().Load([]byte(doc)).Section("section1").Get("k1")
fmt.Println(v1) // 输出: v1
// 获取不同类型值
i := ini.New().Load([]byte(doc))
v2 := i.GetInt("k2")
v3 := i.GetFloat64("k3")
v4 := i.Get("k4")
fmt.Printf("v2:%v v3:%v v4:%v\n", v2, v3, v4)
}
转换为JSON
jsonData := i.Marshal2Json()
fmt.Println(string(jsonData))
// 输出: {"section":{"k":"v"},"section1":{"k1":"v1","k2":"1","k3":"3.5","k4":"0.0.0.0"}}
结构体映射
type TestConfig struct {
K string `ini:"k" json:"k,omitempty"`
K1 int `ini:"k1" json:"k1,omitempty"`
K2 float64 `ini:"k2"`
K3 int64 `ini:"k3"`
User User `ini:"user"`
}
type User struct {
Name string `ini:"name"`
Age int `ini:"age"`
}
func main() {
doc := `
k=v
k1=2
k2=2.2
k3=3
[user]
name=tom
age=-23
`
cfg := TestConfig{}
ini.Unmarshal([]byte(doc), &cfg)
fmt.Println("cfg:", cfg) // 输出: cfg: {v 2 2.2 3 {tom -23}}
}
文件操作
// 读取文件
file := "./test.ini"
iniFile := ini.New().LoadFile(file)
value := iniFile.Section("s2").Get("k2")
fmt.Println(value)
// 实时监控文件
idoc := ini.New().WatchFile(file)
v := idoc.Section("s2").Get("k1")
fmt.Println("v:", v)
// 修改文件后会自动更新
time.Sleep(10 * time.Second)
v = idoc.Section("s2").Get("k1")
fmt.Println("v:", v)
// 写入文件
filename := "./save.ini"
ini.New().Set("a1", 1).Save(filename)
设置INI值
doc := `
k =v
[section]
a=b
c=d
`
ini := New().Load([]byte(doc)).Section("section")
ini.Set("a", 11).Set("c", 12.3).Section("").Set("k", "SET")
// 验证设置的值
v := ini.Section("section").GetInt("a")
if v != 11 {
fmt.Printf("Error: %d", v)
}
完整的INI文件示例
; this is comment
; author levene
; date 2021-8-1
a='23'34?::'<>,.'
c=d
[s1]
k=67676
k1 =fdasf
k2= sdafj3490&@)34 34w2
# comment
# 12.0.0.1
[s2]
k=3
k2=945
k3=-435
k4=0.0.0.0
k5=127.0.0.1
k6=levene@github.com
k7=~/.path.txt
k8=./34/34/uh.txt
k9=234@!@#$%^&*()324
k10='23'34?::'<>,.'
总结
这个INI解析库提供了丰富的功能,包括:
- 从文件或字节切片加载INI配置
- 实时监控文件变化
- 与Go结构体的双向映射
- 转换为JSON格式
- 修改和保存INI文件
通过简单的API,可以轻松地在Go项目中集成INI配置文件的支持。
更多关于golang实现INI文件解析与结构体映射的插件库ini的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang实现INI文件解析与结构体映射的插件库ini的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang INI文件解析与结构体映射:使用ini库
INI文件是一种常见的配置文件格式,Go语言中有一个非常优秀的INI文件解析库go-ini/ini
,它支持将INI文件内容映射到结构体,提供了强大的配置管理功能。
安装ini库
go get gopkg.in/ini.v1
基础用法
1. 加载INI文件
package main
import (
"fmt"
"gopkg.in/ini.v1"
)
func main() {
cfg, err := ini.Load("my.ini")
if err != nil {
fmt.Printf("Fail to read file: %v", err)
return
}
// 获取默认分区(section)的值
fmt.Println("App Mode:", cfg.Section("").Key("app_mode").String())
// 获取指定分区的值
fmt.Println("Data Path:", cfg.Section("paths").Key("data").String())
}
2. 示例INI文件(my.ini)
app_mode = development
[paths]
data = /home/git/grafana
[server]
protocol = http
http_port = 9999
高级功能
1. 结构体映射
type Config struct {
AppMode string `ini:"app_mode"`
Paths struct {
Data string `ini:"data"`
} `ini:"paths"`
Server struct {
Protocol string `ini:"protocol"`
HttpPort int `ini:"http_port"`
} `ini:"server"`
}
func main() {
cfg, err := ini.Load("my.ini")
if err != nil {
fmt.Printf("Fail to read file: %v", err)
return
}
var config Config
err = cfg.MapTo(&config)
if err != nil {
fmt.Printf("Fail to map config: %v", err)
return
}
fmt.Printf("Config: %+v\n", config)
}
2. 写入INI文件
func saveConfig() {
cfg := ini.Empty()
// 创建默认分区
cfg.Section("").Key("app_mode").SetValue("production")
// 创建paths分区
cfg.Section("paths").Key("data").SetValue("/var/lib/grafana")
// 保存到文件
err := cfg.SaveTo("my_new.ini")
if err != nil {
fmt.Printf("Fail to save file: %v", err)
}
}
3. 从结构体生成INI
func structToIni() {
config := Config{
AppMode: "production",
Paths: struct {
Data string `ini:"data"`
}{
Data: "/var/lib/grafana",
},
Server: struct {
Protocol string `ini:"protocol"`
HttpPort int `ini:"http_port"`
}{
Protocol: "https",
HttpPort: 443,
},
}
cfg := ini.Empty()
err := ini.ReflectFrom(cfg, &config)
if err != nil {
fmt.Printf("Fail to reflect from struct: %v", err)
return
}
err = cfg.SaveTo("from_struct.ini")
if err != nil {
fmt.Printf("Fail to save file: %v", err)
}
}
实用技巧
1. 默认值和必须字段
// 获取值,如果不存在则返回默认值
dataPath := cfg.Section("paths").Key("data").MustString("/default/path")
// 必须存在的值,如果不存在会返回错误
httpPort, err := cfg.Section("server").Key("http_port").Int()
if err != nil {
// 处理错误
}
2. 自动加载和保存
type ConfigLoader struct {
cfg *ini.File
}
func NewConfigLoader(filename string) (*ConfigLoader, error) {
cfg, err := ini.Load(filename)
if err != nil {
return nil, err
}
return &ConfigLoader{cfg: cfg}, nil
}
func (c *ConfigLoader) Save() error {
return c.cfg.SaveTo(c.cfg.File.Name())
}
3. 环境变量覆盖
// 在加载配置后,可以用环境变量覆盖某些值
cfg.Section("server").Key("http_port").SetValue(os.Getenv("HTTP_PORT"))
性能考虑
go-ini/ini
库在性能方面表现良好,但如果你的配置文件非常大或需要频繁读取,可以考虑以下优化:
- 使用
cfg.BlockMode = false
禁用并发安全(如果确定不需要) - 缓存解析后的配置对象
- 对于只读场景,使用
ini.LoadSources(ini.LoadOptions{AllowPythonMultilineValues: false})
禁用不需要的特性
总结
go-ini/ini
库提供了完整的INI文件处理能力,包括:
- 解析和写入INI文件
- 结构体与INI文件之间的双向映射
- 类型安全的配置项访问
- 分区(Section)支持
- 注释保持能力
这个库非常适合Go项目中的配置管理需求,既简单又功能强大。