Golang 項目之配置文件

相信對於不少gopher 而言, 我這篇文章,算比較初級,我是一個一年多經驗的golang程序員,有着5年左右的編程經驗。 golang 對於初學者還算友好, 寫代碼很好入門, 但業界對於golang工程與項目的BP卻比較缺乏,或者是有不少方爲此爭論不休,就比依賴管理工具就搞出了許多個,如 知名的有dep, vgo和golang 官方的 go module, 也多是我所知有限的緣故, 但願你們不吝賜教。html

既然要說go項目的配置文件,那對於配置文件先作一個簡單的介紹:mysql

配置文件的格式

yaml

yaml是最近很流行的一種描述語言,上手比較簡單學習成本低,結構清晰, 5分鐘便可掌握全部細節 阮一峯老師的yaml語法教程 一個簡單的示例以下:git

database:
 addr: localhost
 port: 3306
 username: testuser
 password: abcdef
listen:80
複製代碼

ini

ini 文件也是一個比較常見的配置文件的格式,也是幾乎不須要學習成本的,比較簡單,只有兩個概念 區塊與鍵值對, 但表達能力比較有限,格式以下:程序員

[database]
addr = localhost
port = 3306
 [web]
listen = 80
複製代碼

json

json 是一種很是流行的描述語言,表述能力也很是強,很是直觀,一般也是不須要什麼學習成本的, 常見的格式以下:github

{
    "database":{
        "database":"localhost",
        "port":3306
    },
    "web":{
        "listen":80
    }
}
複製代碼

properties

properties 文件對於不少Java程序員應該不陌生,由於在不少spring項目中, 會常常見到這種文件,固然沒有用到過的夜別打我,這種徹底看興趣愛好的, 一個簡單的文件格式以下:golang

addr=localhost
port=3306
複製代碼

Golang 的配置文件

golang 項目爲何要配置文件

對於不少配置相關的項如監聽的端口、數據庫的地址、端口等會比較適合放在配置中,而不是硬編碼在代碼中,所以配置文件的使用仍是比較常見的。 對於使用什麼類型的配置文件你們不須要糾結,根據需求就行了,web

配置文件須要應對的幾種場景

  1. IDE運行/調試時期讀取配置文件
  2. 運行單測或者benchmark Test的時候讀取配置文件
  3. 可執行文件(部署文件)讀取配置文件
  4. 項目中須要僅使用一個配置文件,配置文件能夠在以上三種狀況下均可以被正常讀取

配置文件的放置

通常配置文件會放在項目的根目錄或者比較明顯的位置,固然對於Golang我我的仍是比較推薦放在項目的根目錄, 固然放在其餘目錄也不是不能夠,但可能比較麻煩。spring

怎麼知足配置文件須要應對的幾種場景?

  1. 從項目可執行文件目錄讀取配置文件, 實例代碼以下:
// get config file from where the executables lies
func getConfigFileFromExecutable(fileName string) *os.File {
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		return nil
	}
	f, err := os.Open(path.Join(dir, fileName))
	if err != nil {
		return nil
	}
	return f
}
複製代碼
  1. 從源代碼文件所在目錄遞歸往上層目錄尋找
// read config file
func TestReadConfigFile(t *testing.T) {
	if _, fileNameWithPath, _, ok := runtime.Caller(1); ok {
		d := ReadConfigFile(testFileName, fileNameWithPath)
		if d == nil {
			t.FailNow()
		}
	}
}
複製代碼

這個實現的關鍵點在於 runtime.Caller(1), 此函數能夠返回源代碼所在目錄,但根據參數的不一樣,對於調用的位置要求也不一樣,這裏設置的恰好能夠知足放在項目根目錄的需求sql

一個開源項目

項目地址喜歡的話點個贊(star), 有問題的話能夠提issue. 以聯繫我。數據庫

獲取的方式以下

go get  github.com/winjeg/goconf
複製代碼

此項目採用go module做爲依賴管理方式,但也兼容於傳統的dep做爲依賴管理工具 支持的格式

  1. yaml格式
  2. ini 格式

使用實例

package goconf

import (
	"strings"
	"testing"
)

const (
	testYmlFile = "test.yaml"
	testIniFile = "test.ini"

	host = "10.1.1.1"
	port = 3306
	testName = "tom"
)

type TestYmlConf struct {
	DbAddr string `yaml:"dbAddr"`
	Port   int    `yaml:"dbPort"`
}

type TestMyConf struct {
	Mysql TestIniConf `ini:"mysql"`
	Name  string      `ini:"name"`
}

type TestIniConf struct {
	Host string `ini:"host"`
	Port int    `ini:"port"`
}

func TestYaml2Object(t *testing.T) {
	var x TestYmlConf
	err := Yaml2Object(testYmlFile, &x)
	if err != nil {
		t.FailNow()
	}
	if !strings.EqualFold(x.DbAddr, host) || x.Port != port {
		t.FailNow()
	}
}

func TestIni2Object(t *testing.T) {
	var x TestMyConf
	err := Ini2Object(testIniFile, &x)
	if err != nil {
		t.FailNow()
	}
	if !strings.EqualFold(x.Mysql.Host, host) || x.Mysql.Port != port || !strings.EqualFold(testName, x.Name) {
		t.FailNow()
	}
}
複製代碼

你只須要定義本身須要的配置結構, 指定文件名稱便可正確讀取到配置, 使用起來也很是簡單, 推薦放在項目的根目錄

讀取順序規則

  1. 先從可執行文件的運行目錄讀取配置文件
  2. 若是讀取不到則從項目的源代碼所在目錄讀取, 若是讀取不到,則遞歸往根目錄查找,直到根目錄爲止
  3. 找不到配置文件則會拋出錯誤,找到則不會返回任何錯誤

寫在最後

golang 的配置文件處理方式或許還有不少種,因此若是你們有其餘比較好的法子也能夠分享出來你們一塊兒學習一塊兒進步. 若有任何疑問,歡迎在下方留言評論,或者到上面我項目地址中去提issue.

此文若有轉載,請勿修改原文內容.

相關文章
相關標籤/搜索