golang实现INI文件解析与结构体映射的插件库ini的使用

Golang实现INI文件解析与结构体映射的插件库ini的使用

logo

介绍

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库在性能方面表现良好,但如果你的配置文件非常大或需要频繁读取,可以考虑以下优化:

  1. 使用cfg.BlockMode = false禁用并发安全(如果确定不需要)
  2. 缓存解析后的配置对象
  3. 对于只读场景,使用ini.LoadSources(ini.LoadOptions{AllowPythonMultilineValues: false})禁用不需要的特性

总结

go-ini/ini库提供了完整的INI文件处理能力,包括:

  • 解析和写入INI文件
  • 结构体与INI文件之间的双向映射
  • 类型安全的配置项访问
  • 分区(Section)支持
  • 注释保持能力

这个库非常适合Go项目中的配置管理需求,既简单又功能强大。

回到顶部