本文为转载,原文:iGO实现之路 —— Config
Golang
介绍
相信大多数的程序员在使用各种框架开发的时候,都会有一个配置文件让我们做一些配置,比如说数据库的配置,缓存的配置,调试的配置等等,这些配置只要我们填写之后就会生效。
今天,我就用go语言实现是个读取配置文件的小模块。可能并不是非常的完成,或者还会存在一些不安全的因素。这里我将我的实现写出来,望发现问题的同学们提出来,我们大家共同进步。
源码地址
实现
config 模块的文件列表如下图所示:
文件列表
conf目录为功能模块example目录为测试代码
功能实现
config.go
由于我们的配置文件类型可能是多种多样的,比如ini,json等。所以,我首先得做一个Config的接口:
type Config interface{
GetString(string) string GetInt(string)(int, error)
GetInt64(string)(int64, error)
GetFloat(string)(float64, error)
GetBool(string)(bool, error)}从代码中看,我们的接口比较简单,就是一些从配置文件中读取各种类型的值,这里先暂时支持string,int,int64,float,bool类型的数据读取,后续如有需要再更新。
有了接口,就便于我们同意操作了。下面我们再做一个实例化的函数,这个就有点类型简单工厂模式了。根据参数创建不同类型的实例:
func NewConfig(adapter, filename string) (Config, error){
path, err := GetCurrentPath(filename) if err != nil{ return nil, err
} switch adapter{ case "ini": return GetIniConfig(path) default: return nil, errors.New("系统暂未处理该类型的配置文件")
}
}该函数有2个参数,adapter为我们适配的配置文件类型,如ini, json等。filename为我们的配置文件的相对路径。
代码通过不同的adapter返回不同的实例。该函数中调用了个GetCurrentPath函数。
下面,我们看下GetCurrentPath函数的实现:
func GetCurrentPath(filename string) (path string, err error ){
path, err = filepath.Abs(filename) if err != nil { return
}
path = strings.Replace(path, "\\", "/", -1)
path = strings.Replace(path, "\\\\", "/", -1) return}该函数的作用是将配置文件的相对路径转换为绝对路径。
至此,我们的公用的代码已经完成了。接下来就是各种不同的配置文件的实现了,也就是各种对于Config接口实现的方案。
完整的config.go代码如下:
package conf
import ( "strings"
"errors"
"path/filepath")
type Config interface{
GetString(string) string
GetInt(string)(int, error)
GetInt64(string)(int64, error)
GetFloat(string)(float64, error)
GetBool(string)(bool, error)
}
func NewConfig(adapter, filename string) (Config, error){
path, err := GetCurrentPath(filename) if err != nil{ return nil, err
} switch adapter{ case "ini": return GetIniConfig(path) default: return nil, errors.New("系统暂未处理该类型的配置文件")
}
}
func GetCurrentPath(filename string) (path string, err error ){
path, err = filepath.Abs(filename) if err != nil { return
}
path = strings.Replace(path, "\\", "/", -1)
path = strings.Replace(path, "\\\\", "/", -1) return}ini
ini_config.go
INI文件格式是某些平台或软件上的配置文件的非正式标准,以节(section)和键(key)构成,常用于微软Windows操作系统中。这种配置文件的文件扩展名多为INI,故名。
INI是英文“初始化”(initialization)的缩写。正如该术语所表示的,INI文件被用来对操作系统或特定程序初始化或进行参数设置。
既然知道了ini文件,那么我们就看看怎么去读取其配置吧。
先看下对于IniConfig的结构体定义:
type IniConfig struct{
ConfigMap map[string]string
strcet string}从config.go代码文件中的NewConfig函数中,我们看到了这样一个函数GetIniConfig,而该函数就是对于ini文件配置的初始化:
func GetIniConfig(filename string)(*IniConfig, error){
middle := "."
config := new(IniConfig)
config.ConfigMap = make(map[string]string) //打开文件
file, err := os.Open(filename) if err != nil{ return nil, err
}
defer file.Close()
read := bufio.NewReader(file) for{
b, _, err := read.ReadLine() if err != nil { if err == io.EOF{ break
} return nil, err
}
str := strings.TrimSpace(string(b)) //配置文件中的注释
if strings.Index(str, "#") == 0{ continue
} //配置文件中的前缀处理
n1 := strings.Index(str, "[")
n2 := strings.LastIndex(str, "]") if n1 > -1 && n2 > -1 && n2 > n1 + 1{
config.strcet = strings.TrimSpace(str[n1 + 1 : n2]) continue
} if len(config.strcet) < 1{ continue
} //
eqIndex := strings.Index(str, "=") if eqIndex < 0{ continue
}
eqLeft := strings.TrimSpace(str[0:eqIndex]) if len(eqLeft) < 1{ continue
}
eqRight := strings.TrimSpace(str[eqIndex+1:])
pos := strings.Index(eqRight,"\t#")
val := eqRight if pos > -1{
val = strings.TrimSpace(eqRight[0:pos])
}
pos = strings.Index(eqRight, " #") if pos > -1{
val = strings.TrimSpace(eqRight[0:pos])
}
pos = strings.Index(eqRight, "\t//") if pos > -1{
val = strings.TrimSpace(eqRight[0:pos])
}
pos = strings.Index(eqRight, " //") if pos > -1{
val = strings.TrimSpace(eqRight[0:pos])
} if len(val) < 1{ continue
}
key := config.strcet + middle + eqLeft
config.ConfigMap[key] = strings.TrimSpace(val)
} return config, nil
}然后再有一个按key来获取配置的val的字符串的函数:
func (self *IniConfig) Get(key string)string{
v, ok := self.ConfigMap[key] if ok{ return v
} return ""}剩下来就是对于Config接口的实现了:
func (self *IniConfig) GetString(key string)string{ return self.Get(key)
}
func (self *IniConfig) GetInt(key string)(int, error){ return strconv.Atoi(self.Get(key))
}
func (self *IniConfig) GetInt64(key string)(int64, error){ return strconv.ParseInt(self.Get(key), 10, 64)
}
func (self *IniConfig) GetFloat(key string)(float64, error){ return strconv.ParseFloat(self.Get(key), 64)
}
func (self *IniConfig) GetBool(key string)(bool, error){ return strconv.ParseBool(self.Get(key))
}ini_config.go的实现就这些。当然了,package和import也是肯定有的啦:
package confimport ( "strings" "strconv" "io" "bufio" "os")
上面的这些代码整合到一起就是ini_config.go的完整代码了。
测试
上面那些,也就简单的实现了配置文件的读取功能了。但是能不能用呢?我们简单的做个测试吧。/example/config/app.config中写一些简单的配置信息:
[default]string = stringint = 10int64 = 100000float = 123.456bool = true
然后在/example/test_config.go读取试一下:
package main
import( "fmt"
"igo/conf")
func main(){
config,err := conf.NewConfig("ini", "config/app.config") if err != nil{
fmt.Println(err.Error()) return
}
strVal := config.GetString("default.string")
fmt.Println("string value:", strVal)
intVal, err := config.GetInt("default.int") if err != nil{
fmt.Println("get int value error: ", err.Error())
}
fmt.Println("int value: ", intVal)
int64Val, err := config.GetInt64("default.int64") if err != nil{
fmt.Println("get int64 value error: ", err.Error())
}
fmt.Println("int64 value: ", int64Val)
floatVal, err := config.GetFloat("default.float") if err != nil{
fmt.Println("get float value error: ", err.Error())
}
fmt.Println("float value: ", floatVal)
boolVal, err := config.GetBool("default.bool") if err != nil{
fmt.Println("get bool value error: ", err.Error())
}
fmt.Println("bool value: ", boolVal)
}结果如下:
config测试结果
完
转载请注明出处:
iGO实现之路 —— Config
共同学习,写下你的评论
评论加载中...
作者其他优质文章


