使用go-ini操作ini

地址:

ini 是 Windows 上常用的配置文件格式。MySQL 的 Windows 版就是使用 ini 格式存储配置的。

Hello World

创建ini配置文件:

app_name = awesome web

# possible values: DEBUG, INFO, WARNING, ERROR, FATAL
log_level = DEBUG

[mysql] # section
ip = 127.0.0.1
port = 3306
user = dj
password = 123456
database = awesome

[redis]
ip = 127.0.0.1
port = 6381

使用go-ini读取配置文件:

package main

import (
	"fmt"
	"log"

	"gopkg.in/ini.v1"
)

func main() {
	// 加载ini配置文件
	cfg, err := ini.Load("config/config.ini")
	if err != nil {
		log.Fatal("Fail to read file: ", err)
	}

	// 没有section的kv
	fmt.Println("App Name:", cfg.Section("").Key("app_name").String()) // String返回字符串类型
	fmt.Println("Log Level:", cfg.Section("").Key("log_level").String())

	// mysql section 的 kv
	fmt.Println("MySQL IP:", cfg.Section("mysql").Key("ip").String())
	mysqlPort, err := cfg.Section("mysql").Key("port").Int() // 返回int类型
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("MySQL Port:", mysqlPort)
	fmt.Println("MySQL User:", cfg.Section("mysql").Key("user").String())
	fmt.Println("MySQL Password:", cfg.Section("mysql").Key("password").String())
	fmt.Println("MySQL Database:", cfg.Section("mysql").Key("database").String())

	// redis section 的 kv
	fmt.Println("Redis IP:", cfg.Section("redis").Key("ip").String())
	redisPort, err := cfg.Section("redis").Key("port").Int()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Redis Port:", redisPort)
}

提供的类型方法有:

  • String()

  • Int() / Uint / Float64,这些方法都有可能出现类型转换错误,所以会返回一个err

Must*便捷方法

如果每次取值都需要进行错误判断,那么代码写起来会非常繁琐。为此,go-ini也提供对应的MustType(Type 为Init/Uint/Float64等)方法,这个方法只返回一个值。同时它接受可变参数,如果类型无法转换,就是用可变参数的第一个值作为默认值:

// 如果redis.port的值不是int类型,MustInt就会返回默认值6381
fmt.Println("redis Port:", cfg.Section("redis").Key("port").MustInt(6381))

分区操作

package main

import (
	"fmt"
	"log"

	"gopkg.in/ini.v1"
)

func main() {
	// 加载ini配置文件
	cfg, err := ini.Load("config/config.ini")
	if err != nil {
		log.Fatal("Fail to read file: ", err)
	}

	sections := cfg.Sections() // 返回所有分区对象 *[]Section
	fmt.Println(sections) // [0xc000100620 0xc000100770 0xc000100a10]

	names := cfg.SectionStrings() // 获取所有分区的名称
	fmt.Println(names) // [DEFAULT mysql redis]

}

写入配置

写入配置有两种,一种是写入到文件中,一种是写入到write流中:

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

cfg.WriteTo(writer)
cfg.WriteToIndent(writer, "\t")
package main

import (
  "fmt"
  "os"

  "gopkg.in/ini.v1"
)

func main() {
  cfg := ini.Empty()

  defaultSection := cfg.Section("")
  defaultSection.NewKey("app_name", "awesome web")
  defaultSection.NewKey("log_level", "DEBUG")

  mysqlSection, err := cfg.NewSection("mysql")
  if err != nil {
    fmt.Println("new mysql section failed:", err)
    return
  }
  mysqlSection.NewKey("ip", "127.0.0.1")
  mysqlSection.NewKey("port", "3306")
  mysqlSection.NewKey("user", "root")
  mysqlSection.NewKey("password", "123456")
  mysqlSection.NewKey("database", "awesome")

  redisSection, err := cfg.NewSection("redis")
  if err != nil {
    fmt.Println("new redis section failed:", err)
    return
  }
  redisSection.NewKey("ip", "127.0.0.1")
  redisSection.NewKey("port", "6381")

  err = cfg.SaveTo("my.ini")
  if err != nil {
    fmt.Println("SaveTo failed: ", err)
  }

  err = cfg.SaveToIndent("my-pretty.ini", "\t")
  if err != nil {
    fmt.Println("SaveToIndent failed: ", err)
  }

  cfg.WriteTo(os.Stdout)
  fmt.Println()
  cfg.WriteToIndent(os.Stdout, "\t")
}

映射结构体

注意:所有的结构体字段必须是导出的,否则不会映射

package main

import (
	"fmt"

	"gopkg.in/ini.v1"
)

type Config struct {
	AppName   string `ini:"app_name"`
	LogLevel  string `ini:"log_level"`

	MySQL     MySQLConfig `ini:"mysql"`
	Redis     RedisConfig `ini:"redis"`
}

type MySQLConfig struct {
	IP        string `ini:"ip"`
	Port      int `ini:"port"`
	User      string `ini:"user"`
	Password  string `ini:"password"`
	Database  string `ini:"database"`
}

type RedisConfig struct {
	IP      string `ini:"ip"`
	Port    int `ini:"port"`
}

func main() {
	cfg, err := ini.Load("config/config.ini")
	if err != nil {
		fmt.Println("load my.ini failed: ", err)
	}

	c := Config{}
	cfg.MapTo(&c)

	fmt.Println(c)
}

映射单个分区

mysqlCfg := MySQLConfig{}
err = cfg.Section("mysql").MapTo(&mysqlCfg)

根据结构体生成配置

cfg := ini.Empty()

c := Config {
  AppName:     "awesome web",
  LogLevel:     "DEBUG",
  MySQL: MySQLConfig {
    IP:     "127.0.0.1",
    Port:    3306,
    User:    "root",
    Password:"123456",
    Database:"awesome",
  },
  Redis: RedisConfig {
    IP:        "127.0.0.1",
    Port:    6381,
  },
}

err := ini.ReflectFrom(cfg, &c)
if err != nil {
  fmt.Println("ReflectFrom failed: ", err)
  return
}

err = cfg.SaveTo("my-copy.ini")
if err != nil {
  fmt.Println("SaveTo failed: ", err)
  return
}

最后更新于