goconfig

goconfig简介

goconfig是一个由Go语言开发的针对windows下常见的ini格式的配置文件解析器。该解析器在涵盖了所有ini文件操作的基础之上,又针对Go语言实际开发过程中遇到的一些需求进行了扩展。相对于其他ini文件解析器而言,该解析器最大的优势在于对注释的极佳支持;除此之外,支持多个配置文件覆盖加载也是非常特别但好用的功能。

主要特性

  • 提供与windows API 一模一样的操作方式
  • 支持递归读取分区
  • 支持自增键名
  • 支持对注释的读写操作
  • 支持直接返回指定类型的键值
  • 支持多个文件覆盖加载

下载安装

1:通过gopm安装
gopm get github.com/Unknwon/goconfig
2:通过go get 安装
go get github.com/Unknwon/goconfig

基本使用方法

  • 加载配置文件
cfg, err := goconfig.LoadConfigFile("conf.ini")
	if err != nil {
		log.Fatalf("无法加载配置文件: %s", err)
	}
  • 基本读写操作
value, err := cfg.GetValue(goconfig.DEFAULT_SECTION, "key_default")
	if err != nil {
		log.Fatalf("无法获取键值(%s): %s", "key_default", value)
	}
log.Printf("%s > %s: %s", goconfig.DEFAULT_SECTION, "key_default", value)

isInsert := cfg.SetValue(goconfig.DEFAULT_SECTION, "key_default12", "这是新的值")
	//如果返回值为false就证明这个setvalue是覆盖原来的值,如果是true,就证明setvalue是创建一个新的键值对
log.Printf("设置键值 %s 为插入操作: %v", "key_default", isInsert)
  • 注释的读写操作
comment := cfg.GetSectionComments("super")
log.Printf("分区 %s 的注释: %v", "super", comment) 
//读取super分区的注释

v := cfg.SetSectionComments("super", "# 这是新的分区注释")
log.Printf("分区 %s 的注释被插入或删除: %v", "super", v) 
//返回为true 被插入或删除,如果是false表示这个注释是被重写的	
  • 类型转换读取
vInt, err := cfg.Int("must", "int")
	if err != nil {
		log.Fatalf("无法获取键值(%s): %s", "int", err)
	}
log.Printf("%s > %s: %v", "must", "int", vInt)
  • Must系列的方法
vBool := cfg.MustBool("must", "bool")
log.Printf("%s > %s: %v", "must", "bool", vBool)
//must系列方法不会返回一个err,当错误发生的时候,默认会返回这个类型的零值
  • 删除指定键值
	ok := cfg.DeleteKey("must", "string")
	log.Printf("删除键值 %s 是否成功: %v", "string", ok)
  • 保存配置文件
err = goconfig.SaveConfigFile(cfg, "conf_save.ini")
	if err != nil {
		log.Fatalf("无法保存配置文件: %s", err)
	}

完整代码

package main

import (
	"log"

	"github.com/Unknwon/goconfig"
)

func main() {
	//有两个返回值,第一个是configfile对象,第二个是一个错误
	cfg, err := goconfig.LoadConfigFile("conf.ini")
	if err != nil {
		log.Fatalf("无法加载配置文件: %s", err)
	}
	value, err := cfg.GetValue(goconfig.DEFAULT_SECTION, "key_default")
	if err != nil {
		log.Fatalf("无法获取键值(%s): %s", "key_default", value)
	}
	log.Printf("%s > %s: %s", goconfig.DEFAULT_SECTION, "key_default", value)
	isInsert := cfg.SetValue(goconfig.DEFAULT_SECTION, "key_default12", "这是新的值")
	//如果返回值为false就证明这个setvalue是覆盖原来的值,如果是true,就证明setvalue是创建一个新的键值对
	log.Printf("设置键值 %s 为插入操作: %v", "key_default", isInsert)

	comment := cfg.GetSectionComments("super")
	log.Printf("分区 %s 的注释: %v", "super", comment) //读取super分区的注释
	v := cfg.SetSectionComments("super", "# 这是新的分区注释")
	log.Printf("分区 %s 的注释被插入或删除: %v", "super", v) //返回为true 被插入或删除,如果是false表示这个注释是被重写的
	vInt, err := cfg.Int("must", "int")
	if err != nil {
		log.Fatalf("无法获取键值(%s): %s", "int", err)
	}
	log.Printf("%s > %s: %v", "must", "int", vInt)
	
	vBool := cfg.MustBool("must", "bool")
	log.Printf("%s > %s: %v", "must", "bool", vBool)
	//must系列方法不会返回一个err,当错误发生的时候,默认会返回这个类型的零值

	ok := cfg.DeleteKey("must", "string")
	log.Printf("删除键值 %s 是否成功: %v", "string", ok)
	err = goconfig.SaveConfigFile(cfg, "conf_save.ini")
	if err != nil {
		log.Fatalf("无法保存配置文件: %s", err)
	}

}

高级使用方法

  • 多文件覆盖加载
package main

import (
	"log"

	"github.com/Unknwon/goconfig"
)

func main() {
	cfg, err := goconfig.LoadConfigFile("conf1.ini", "conf2.ini")
	//当键值有冲突的时候,以后面加载的配置文件为准
	if err != nil {
		log.Fatalf("无法加载配置文件: %s", err)
	}
	value, err := cfg.GetValue("", "key_default")
	if err != nil {
		log.Printf("无法获取键值(%s): %s", "key_default", err)
		return
	}
	log.Printf("%s > %s: %s", goconfig.DEFAULT_SECTION, "key_default", value)
	//追加配置文件
	err = cfg.AppendFiles("conf3.ini")
	if err != nil {
		log.Fatalf("无法追加配置文件: %s", err)
	}
}

  • 配置文件重载
//配置文件重载
err = cfg.Reload()
  • 为Must系列方法设置缺省值
vBoot := cfg.MustBool("must", "bool404", true) 
//这里404不存在,理应返回false,我们这里将缺省值设置为true
log.Printf("%s > %s: %v", "must", "bool404", vBoot)
  • 递归读取键值
//配置文件内容
; Google
google=www.google.com
search=http://%(google)s

//code
val, err := cfg.GetValue("", "search")
	if err != nil {
		log.Printf("无法获取键值(%s): %s", "search", err)
	}
log.Printf("%s > %s : %s", goconfig.DEFAULT_SECTION, "search", val)
//默认会递归的读取键值
//结果是:
2017/10/17 17:01:09 DEFAULT > search : http://www.google.com
  • 子孙分区覆盖读取
//配置文件
[parent]
name=john
relation=father
sex=male
age=32

[parent.child]
age=3
//code
	value, err = cfg.GetValue("parent.child", "age")
	if err != nil {
		log.Printf("无法获取键值(%s): %s", "age", err)
	}
	log.Printf("%s > %s : %s", "parent.child", "age", value)

	value, err = cfg.GetValue("parent.child", "sex")
	if err != nil {
		log.Printf("无法获取键值(%s): %s", "sex", err)
	}
	log.Printf("%s > %s : %s", "parent.child", "sex", value)
//可以看到在子分区没有得key,它会从父分区读取这个key的值然后进行返回,注意分区命名最好不要包括“ . ”
  • 自增键名获取和获取整个分区
//配置文件是:
; Auto increment by setting key to "-"
[auto increment]
-=hello
-=go
-=config

//code
	sec, err := cfg.GetSection("auto increment")
	if err != nil {
		log.Printf("无法获取分区: %s", err)
	}
	log.Println(sec)
//结果:
2017/10/17 17:16:28 map[#1:hello #2:go #3:config]
原文地址:https://www.cnblogs.com/skymyyang/p/7723046.html