读取Go项目中的配置文件(.property和.json)

410 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情

在项目中(至少是SpringBoot)我们一般会以如下格式配置一些参数:

modelPath = "aaaa.pth"
config1 = "ON"
config2 = "OFF"

在读取配置文件时,可以通过Scanner逐行读取。 文件目录结构如下: -property -property.go -config.property -main.go

property.go实现Read函数,能够根据传来的key查找对应的value,main.go中能够调用Read函数,其中Read函数名首字母要大写,否则main包中的文件不能调用。

config.property

modelPath = "aaaa.pth"
config1 = "ON"
config2 = "OFF"

property.go

package property

import (
	"bufio"
	"log"
	"os"
	"path/filepath"
	"strings"
)

func Read(key string) string {
	//读取配置文件
	basedir, err := os.Getwd()
	if err != nil {
		log.Fatal("获取当前目录失败", err)
	}
	configPath := filepath.Join(basedir, "config.property")
	conf, err := os.Open(configPath)
	if err != nil {
		log.Fatal("配置文件读取失败", err)
	}

	defer func() {
		if err := conf.Close(); err != nil {
			log.Fatal("配置文件关闭失败", err)
		}
	}()

	//读取配置文件内容
	sc := bufio.NewScanner(conf)
	line := ""
	//需要一个slice存放key和value
	slice := make([]string, 2)

	for sc.Scan() {
		line = sc.Text()
		//判断是否是注释
		if strings.HasPrefix(line, "#") {
			continue
		}
		//判断是否是空行
		if strings.TrimSpace(line) == "" {
			continue
		}
		//判断是否是key=value的形式
		slice = strings.Split(line, "=")
		if len(slice) == 2 {
			if strings.Trim(slice[0], " ") == key {
				return strings.Trim(slice[1], " ")
			}
		}
	}
	return ""
}

main.go

package main

import (
	"ReadFile/property"
	"flag"
	"fmt"
)

func main() {
	//用户可以选择查看什么参数
	content := flag.String("config_key", "modelPath", "请输入需要查看的参数")
	flag.Parse()
	//调用property包中的Read方法
	value := property.Read(*content)
	fmt.Printf("key:%v\nvalue:%v\n", *content, value)
}

代码分析

最好使用os.Getwd()先获取工作目录,工作目录就是go.mod所在目录,而不是本例中property.go所在的目录。所以如果我们将config.property放在property文件夹下,将会出现以下错误。

配置文件读取失败open C:\Users\饿了没\Desktop\Go\ReadFile\config.property: The system cannot find the file specified.
解析json配置文件

要读取JSON配置文件,我们可以使用Go语言中内置的encoding/json包。

首先,需要将JSON配置文件解析为Go语言中的结构体,我们可以使用Decoder.Decode来实现这一点。

现在我们有名为config.json的JSON配置文件,其内容如下面config.json所示,我们可以在读取json文件的代码中创建一个Config结构体,将其与我们的配置文件关联起来。

type Config struct {
	Db struct {
		Host     string `json:"host"`
		Port     string `json:"port"`
		Username string `json:"username"`
		Password string `json:"password"`
	} `json:"db"`
	Server struct {
		Port string `json:"port"`
	} `json:"server"`
}

读取json文件的关键代码如下:

file, _ := os.Open("config.json")
defer file.Close()
decoder := json.NewDecoder(file) 
config := Config{}

最后是完整的读取json的代码:

文件目录结构如下 -property -config_json.go -config.json -main.go

我们可以使用GO的json包来解析json文件,如下:

config.json

{
    "db": {
    "host": "localhost",
    "port": "3306",
    "username": "root",
    "password": "root"
    },
    "server": {
    "port": "8080"
    }
}

config_json.go

package property

import (
	"encoding/json"
	"log"
	"os"
	"path/filepath"
)

type Config struct {
	Db struct {
		Host     string `json:"host"`
		Port     string `json:"port"`
		Username string `json:"username"`
		Password string `json:"password"`
	} `json:"db"`
	Server struct {
		Port string `json:"port"`
	} `json:"server"`
}

func ReadJson(filename string) Config {
	//读取配置文件
	basedir, err := os.Getwd()
	if err != nil {
		log.Fatal("获取当前目录失败", err)
	}
	configPath := filepath.Join(basedir, filename)
	conf, err := os.Open(configPath)
	if err != nil {
		log.Fatal("配置文件读取失败", err)
	}

	defer func() {
		if err := conf.Close(); err != nil {
			log.Fatal("配置文件关闭失败", err)
		}
	}()

	//读取配置文件内容
	var config Config
	decoder := json.NewDecoder(conf) //创建一个解码器,和文件绑定
	err = decoder.Decode(&config)    //解码
	if err != nil {
		log.Fatal("配置文件解析失败", err)
	}
	return config
}

main.go

package main

import (
	"ReadFile/property"
	"flag"
	"fmt"
)

func main() {
	//用户可以指定配制文件
	filename := flag.String("config_path", "config.json", "指定要读取的配置文件")
	flag.Parse()

	//调用property包中的ReadJson方法

	config := property.ReadJson(*filename)
	fmt.Printf("%v", config)
}

同样,我们使用了os.Getwd()来获取当前工作目录,然后用绝对路径打开json文件。

返回结果:

{{localhost 3306 root root} {8080}}