最近遇到一个需求, 需要做一个配置文件读取功能,用key:values的形式返回给前端, 但是我们有5种服务
然后如果5种服务的配置文件都不一样,比如有的以:分割, 有的以=分割,有的是csv,甚至有的配置项我们不希望暴露给用户, 那么冗余代码会非常多, 所以我就想优化一下代码逻辑
首先我们总结一下读取配置文件的功能顺序
- 打开配置文件
- 按行读取
- 不符合条件的行跳过
- 以指定的分隔符切割, 拿到配置的key, value
- 返回
所以冗余的代码在于
- 打开文件
- 按行读取
所以我们就把这两个冗余代码给抽象出来
func (c *Collector) GetConfigHandler(service string) (map[string]string, error) {
//拿到配置文件路径
configFilePath, ok := configFilePathMap[service]
if !ok {
return map[string]string{}, code.ServiceNotNout
}
var (
err error
data = map[string]string{}
file *os.File
k, v string
)
//打开文件
if file, err = os.Open(configFilePath); err != nil {
return data, err
}
defer file.Close()
//拿到处理函数
handler, ok := configFileHandlerMap[service]
if !ok {
return data, code.HandlerNotFind
}
//文件主转为buffio
bufF := bufio.NewReader(file)
for {
//逐行读取
line, _, _err := bufF.ReadLine()
if _err != nil {
if _err == io.EOF {
break
} else {
return data, _err
}
}
strLine := string(line)
//把行内容送往对应的处理函数
if k, v = handler(strLine); k == "" {
continue
}
//拿到处理后的结果赋值给map
data[k] = v
}
return data, nil
}
configFilePathMap就是定义了每一个服务的配置文件路径
configFileHandlerMap里就是每一个服务对应的处理函数, 下面是一个例子
func HwmConfigParse(strLine string) (string, string) {
if strings.HasPrefix(strLine, "#") {
return "", ""
}
if !strings.Contains(strLine, "=") {
return "", ""
}
tmp := strings.Split(strLine, "=")
return strings.TrimSpace(tmp[0]), strings.TrimSpace(tmp[1])
}
当行内容以#开头时,说明这是注释,我们跳过
当内容包含=号时, 说明这是配置行,然后我们用=号切割 把配置key和value返回
当我们的解析函数遇到调用处理函数返回的是””, “”时,意味着这行需要跳过, 否则我们就把返回值赋值给map,这样就实现了通用的配置文件读取
发表回复