最近在做用golang生成yaml文件时,在git上看见viper这个库使用很多,去试用了一下,发现确实操作简单(get、set)那一套获取生成。但是我发现生成的yaml文件是按照(a->b->c)字典序排列的,看起来就很难受有没有。所以我采用折中的办法去完成此功能。
读取文件的方式
因为我的项目中这个功能是通过一个yaml模板,生成指定路径的yaml文件,所以我放弃了vipe库,直接使用读取文件的方式。
//import (
// "bufio"
// "fmt"
// "io"
// "os"
// "strings"
//)
/**
*@func 产生当前用户的config配置文件
*@param yamlpath yaml模板路径
*@param newyamlpath 新yaml路径
*@param newyamlname 产生的新文件名
*@param certificate 用户证书
*@param privatekey 用户私钥
*@return error
*/
func CreateUserYaml(yamlpath string, newyamlpath string, newyamlname string, certificate string, privatekey string) error {
fileName := yamlpath
in, err := os.Open(fileName)
if err != nil {
fmt.Println("open file fail:", err)
return err
}
defer in.Close()
os.MkdirAll(newyamlpath, 0766)
out, err := os.OpenFile(newyamlpath+"/"+newyamlname, os.O_RDWR|os.O_CREATE, 0766)
if err != nil {
fmt.Println("Open write file fail:", err)
return err
}
defer out.Close()
br := bufio.NewReader(in)
index := 1
for {
line, _, err := br.ReadLine()
if err == io.EOF {
break
}
if err != nil {
fmt.Println("read err:", err)
return err
}
//var newLine string
if strings.Contains(string(line), "${usercertificate}$") {
newLine := strings.Replace(string(line), "${usercertificate}$", certificate, 1)
_, err = out.WriteString(newLine + "\n")
if err != nil {
fmt.Println("write to file fail:", err)
return err
}
} else if strings.Contains(string(line), "${userprivatekey}$") {
newLine := strings.Replace(string(line), "${userprivatekey}$", privatekey, 1)
_, err = out.WriteString(newLine + "\n")
if err != nil {
fmt.Println("write to file fail:", err)
return err
}
} else {
_, err = out.WriteString(string(line) + "\n")
if err != nil {
fmt.Println("write to file fail:", err)
return err
}
}
index++
}
return nil
}
上述功能是一个yaml文件的全局替换,简单思路就是读取文件流到替换的那一行,完成替换功能。这是提供了一个思路,不一定非要想着如何操作yaml,有时候可以使用最原始的方法,直接读取文件流。也是给自己提个醒,不要学太死板。