实际项目中,要读取一些json等配置文件。今天就来说一说,Golang 是如何读取YAML,JSON,INI等配置文件的。
一. go读取json配置文件
JSON 应该比较熟悉,它是一种轻量级的数据交换格式。层次结构简洁清晰 ,易于阅读和编写,同时也易于机器解析和生成。
-
1.创建 conf.json:
{
"enabled": true,
"path": "/usr/local"
} -
2.新建config_json.go:
package main
import (
"encoding/json"
"fmt"
"os"
)type configuration struct {
Enabled bool
Path string
}func main() {
// 打开文件
file, _ := os.Open("conf.json")// 关闭文件 defer file.Close() //NewDecoder创建一个从file读取并解码json对象的*Decoder,解码器有自己的缓冲,并可能超前读取部分json数据。 decoder := json.NewDecoder(file) conf := configuration{} //Decode从输入流读取下一个json编码值并保存在v指向的值里 err := decoder.Decode(&conf) if err != nil { fmt.Println("Error:", err) } fmt.Println("path:" + conf.Path)
}
启动运行后,输出如下:
D:\Go_Path\go\src\configmgr>go run config_json.go
path:/usr/local
1.2 复杂json解析
假设test.json内容如下,如何解析?
{
"pids":{
"default":{
"pid":"1844_71935560",
"desc":"app1"
},
"shehui":{
"pid":"1844_101751664",
"desc":"app2"
}
},
"top_words":[
"邓紫棋",
"沈腾",
"关晓彤",
"鹿晗"
]
}
通过json转struct工具转换:
Golang: Convert JSON to Struct
JSON-to-Go: Convert JSON to Go instantly
转化后的struct
type configuration struct {
Pids struct {
Default struct {
Pid string `json:"pid"`
Desc string `json:"desc"`
} `json:"default"`
Shehui struct {
Pid string `json:"pid"`
Desc string `json:"desc"`
} `json:"shehui"`
} `json:"pids"`
TopWords []string `json:"top_words"`
}
demo实现:
package main
import (
"encoding/json"
"fmt"
"os"
)
type configuration struct {
Pids struct {
Default struct {
Pid string `json:"pid"`
Desc string `json:"desc"`
} `json:"default"`
Shehui struct {
Pid string `json:"pid"`
Desc string `json:"desc"`
} `json:"shehui"`
} `json:"pids"`
TopWords []string `json:"top_words"`
}
func parseJsonConfig(filepath string) (conf configuration) {
// 打开文件
file, _ := os.Open(filepath)
// 关闭文件
defer file.Close()
conf = configuration{}
//NewDecoder创建一个从file读取并解码json对象的*Decoder,解码器有自己的缓冲,并可能超前读取部分json数据。
//Decode从输入流读取下一个json编码值并保存在v指向的值里
err := json.NewDecoder(file).Decode(&conf)
if err != nil {
fmt.Println("Error:", err)
}
return
}
func main() {
pdd := parseJsonConfig("D:\\LearnGo\\FirstGo\\10-文件操作\\test3.json")
fmt.Println(pdd)
fmt.Println(pdd.Pids.Shehui.Pid)
}
再继续来个案例:
假设json文件内容如下,想读取top_words中name的值,要怎么解析获取?
{
"pids":{
"default":{
"pid":"1844_71935560",
"desc":"app1"
},
"shehui":{
"pid":"1844_101751664",
"desc":"app2"
}
},
"top_words":[
{
"name": "cc",
"age": 18
},
{
"name": "test",
"age": 20
}
]
}
demo实现
package main
import (
"encoding/json"
"fmt"
"os"
)
type configuration1 struct {
Pids struct {
Default struct {
Desc string `json:"desc"`
Pid string `json:"pid"`
} `json:"default"`
Shehui struct {
Desc string `json:"desc"`
Pid string `json:"pid"`
} `json:"shehui"`
} `json:"pids"`
TopWords []struct {
Age int64 `json:"age"`
Name string `json:"name"`
} `json:"top_words"`
}
func parseJsonConfig1(filepath string) (conf configuration1) {
// 打开文件
file, _ := os.Open(filepath)
// 关闭文件
defer file.Close()
conf = configuration1{}
//NewDecoder创建一个从file读取并解码json对象的*Decoder,解码器有自己的缓冲,并可能超前读取部分json数据。
//Decode从输入流读取下一个json编码值并保存在v指向的值里
err := json.NewDecoder(file).Decode(&conf)
if err != nil {
fmt.Println("Error:", err)
}
return
}
func main() {
pdd := parseJsonConfig1("D:\\LearnGo\\FirstGo\\10-文件操作\\test4.json")
fmt.Println(pdd)
//遍历string切片获取name的值
for _, i := range pdd.TopWords {
name := i.Name
fmt.Println(name)
}
}
运行结果:
{{{app1 1844_71935560} {app2 1844_101751664}} [{18 cc} {20 test}]}
cc
test
最后一个工作用到的案例:读取json文件中的规则,做正则匹配,这里没有进行匹配操作,后续用到加上
{
"reverse_shell_rule":[
{
"id":"R10000",
"regex":"socat\\s+TCP4:\\w+\\.\\w+\\.\\w+\\.\\w+:(\\w+)\\s+.*"
},
{
"id":"R10001",
"regex":"exec\\s+\\d+\\<\\>\/\\w+\/.*"
}
]
}
// 读取JSON文件 将内容转为结构对象 然后更改数据
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
)
type ReverseJson struct {
ReverseShellRule []struct {
ID string `json:"id"`
Regex string `json:"regex"`
} `json:"reverse_shell_rule"`
}
func main() {
var data ReverseJson
// 读取JSON文件内容 返回字节切片
bytes, _ := ioutil.ReadFile("D:\\LearnGo\\FirstGo\\10-文件操作\\test.json")
// 打印时需要转为字符串
fmt.Println(string(bytes))
// 将字节切片映射到指定结构上
json.Unmarshal(bytes, &data)
//fmt.Println("*** unmarshal result: ***")
// 打印对象结构
for _, reg := range data.ReverseShellRule {
rule := reg.Regex
fmt.Println(rule)
}
}
二、 go读取.ini配置文件
INI文件格式是某些平台或软件上的配置文件的非正式标准,由节(section)和键(key)构成,比较常用于微软Windows操作系统中。这种配置文件的文件扩展名为INI。
-
1.创建 conf.ini:
[Section]
enabled = true
path = /usr/local # another comment -
2.下载第三方库:go get gopkg.in/gcfg.v1
-
3.新建 config_ini.go:
package main
import (
"fmt"
gcfg "gopkg.in/gcfg.v1"
)func main() {
config := struct {
Section struct {
Enabled bool
Path string
}
}{}err := gcfg.ReadFileInto(&config, "conf.ini") if err != nil { fmt.Println("Failed to parse config file: %s", err) } fmt.Println(config.Section.Enabled) fmt.Println(config.Section.Path)
}
启动运行后,输出如下:
D:\Go_Path\go\src\configmgr>go run config_ini.go
true
/usr/local
三、go读取yaml配置文件
yaml 可能比较陌生一点,但是最近却越来越流行,尤其在SpringBoot中的application.yml或者application.yaml中使用非常广泛。也就是一种标记语言。层次结构也特别简洁清晰 ,易于阅读和编写,同时也易于机器解析和生成。
golang的标准库中暂时没有给我们提供操作yaml的标准库,但是github上有很多优秀的第三方库开源给我们使用。
-
- 创建 conf.yaml:
enabled: true
path: /usr/local
-
2.下载第三方库:go get gopkg.in/yaml.v2
-
3.创建 config_yaml.go:
package main
import (
"fmt"
"io/ioutil"
"log""gopkg.in/yaml.v2"
)
type conf struct {
Enabled boolyaml:"enabled"
//yaml:yaml格式 enabled:属性的为enabled
Path stringyaml:"path"
}func (c *conf) getConf() *conf {
yamlFile, err := ioutil.ReadFile("conf.yaml")
if err != nil {
log.Printf("yamlFile.Get err #%v ", err)
}err = yaml.Unmarshal(yamlFile, c) if err != nil { log.Fatalf("Unmarshal: %v", err) } return c
}
func main() {
var c conf
c.getConf()
fmt.Println("path:" + c.Path)
}
启动运行后,输出如下:
D:\Go_Path\go\src\configmgr>go run config_yaml.go
path:/usr/local
最后 以上,就把golang 读取配置文件的方法,都介绍完了。大家可以拿着代码运行起来看看。
参考资料:
Go 语言解析 JSON 文件 - 知乎 Go 语言解析 JSON 文件(推荐)