goconfig - INI 解析器
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]
goconfig - INI 解析器的更多相关文章
- C++ ini解析器
在gitee上找到的一个很好用的ini文件解析器,纯C++代码,移植方便. 项目地址:https://gitee.com/sollyu/IniParser 稍微修改了下,去掉了Windows平台相关定 ...
- golang开发:类库篇(四)配置文件解析器goconfig的使用
为什么要使用goconfig解析配置文件 目前各语言框架对配置文件书写基本都差不多,基本都是首先配置一些基础变量,基本变量里面有环境的配置,然后通过环境变量去获取该环境下的变量.例如,生产环境跟测试环 ...
- Atiit 如何手写词法解析器
Atiit 如何手写词法解析器 1.1. 通过编程直接从正则->nfa->dfa->表驱动词法解析一条龙自动生成.那是用程序自动生成是需要这样的,自己手写完全不必要这么复杂1 1.2 ...
- configparser_配置解析器
configparser:配置解析器 import configparser config = configparser.ConfigParser() #配置文件 config[', 'Compres ...
- $Django Rest Framework-频率组件,解析器
1 频率组件 #自定义组件写频率认证(重点继承BaseThrottle) from rest_framework.throttling import BaseThrottle import time ...
- python接口自动化测试 - configparser配置文件解析器详细使用
configparser简介 ConfigParser模块已在Python 3中重命名为configparser 该模块定义了ConfigParser类. ConfigParser类实现一种基本的配置 ...
- Python3-configparser模块-配置文件解析器
Python3中的configparser模块主要用于处理类似于windows ini 文件结构的配置文件 1.configparser模块提供实现基本配置语言的ConfigParser类 2.配置文 ...
- XML技术之DOM4J解析器
由于DOM技术的解析,存在很多缺陷,比如内存溢出,解析速度慢等问题,所以就出现了DOM4J解析技术,DOM4J技术的出现大大改进了DOM解析技术的缺陷. 使用DOM4J技术解析XML文件的步骤? pu ...
- AFN解析器里的坑
AFN框架是用来用来发送网络请求的,它的好处是可以自动给你解析JSON数据,还可以发送带参数的请求AFN框架还可以监测当前的网络状态,还支持HTTPS请求,分别对用的类为AFNetworkReacha ...
随机推荐
- Ubuntu12搭建nutch1.2+tomcat7+jdk1.6
Ubuntu12搭建nutch1.2+tomcat7+jdk1.6 所用软件:jdk-6u24-linux-i586.bin apache-tomcat-7.0.27.tar.gz apache-nu ...
- JVM可支持的最大线程数
转微博,因为他也是转载 不知道原出处 一.认识问题: 首先我们通过下面这个 测试程序 来认识这个问题:运行的环境 (有必要说明一下,不同环境会有不同的结果):32位 Windows XP,Sun J ...
- hdu4742
题意:给定3维的n(<=100000)个点,求最长不下降子序列长度(对于1和2两个点,2可以放在1后面,x1<=x2,y1<=y2,z1<=z2 ),并求出有多少种方案. 思路 ...
- TryEnterCriticalSection___Delphi
VOID EnterCriticalSection:非阻塞函数.将当前线程对指定临界区的引用计数减1:在使用计数变为零时,另一等待此临界区的一个线程将被唤醒. BOOL TryEnterCritica ...
- Android-Java-synchronized同步代码块的使用场景
synchronized同步代码块的使用场景 (满足以下两种条件,就要考虑使用synchronize同步代码块了) 1.被synchronized同步代码块{同步的代码},是被多次异步调用,什么叫多次 ...
- [ASE][Daily Scrum]11.06
我们的<坦克大战·无尽>正式开始动工了,今天的任务计划如下~ [Plan] View Shilin Liu 搭建好开发环境 收集素材 Control Jiafan Zhu ...
- Hibernate在PostgreSQL上执行sum函数导致数据失真的问题
有一段通过Hibernate从PostgreSQL上进行sum统计的简单代码,但统计结果却导致数据失真,不知原因何在,求指教! Java代码片段如下: public List<Object> ...
- ASP.NET微信公众号用于给指定OpenId用户发送红包
ASP.NET微信公众号用于给指定OpenId用户发送红包 微信公众号要实现对指定用户发送红包,必须指定一个存放兵发放金额的商户号,在微信商户平台里面申请商户号并获取相关参数例如发送红包所要用到的安全 ...
- 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组
[源码下载] 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组 作者:webabcd 介绍背水一战 Windows 10 之 控件 ...
- springboot + mybatis + 多数据源
此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验 在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源. 代码结构: 简要原理: 1) ...