depvgogo module

既然要说go项目的配置文件,那对于配置文件先做一个简单的介绍:

配置文件的格式

yaml

yaml是最近很流行的一种描述语言,上手比较简单学习成本低,结构清晰, 5分钟即可掌握所有细节 阮一峰老师的yaml语法教程 一个简单的示例如下:

database:
    addr: localhost
    port: 3306
    username: testuser
    password: abcdef
listen:80
复制代码

ini

ini 文件也是一个比较常见的配置文件的格式,也是几乎不需要学习成本的,比较简单,只有两个概念 区块与键值对, 但表达能力比较有限,格式如下:

[database]
addr = localhost
port = 3306

[web]
listen = 80
复制代码

json

json 是一种非常流行的描述语言,表述能力也非常强,非常直观,通常也是不需要什么学习成本的, 常见的格式如下:

{
    "database":{
        "database":"localhost",
        "port":3306
    },
    "web":{
        "listen":80
    }
}
复制代码

properties

properties 文件对于很多Java程序员应该不陌生,因为在很多spring项目中, 会经常见到这种文件,当然没有用到过的夜别打我,这种完全看兴趣爱好的, 一个简单的文件格式如下:

addr=localhost
port=3306
复制代码

Golang 的配置文件

golang 项目为什么要配置文件

对于很多配置相关的项如监听的端口、数据库的地址、端口等会比较适合放在配置中,而不是硬编码在代码中,因此配置文件的使用还是比较常见的。 对于使用什么类型的配置文件大家不需要纠结,根据需求就好了,

配置文件需要应对的几种场景

  1. IDE运行/调试时期读取配置文件
  2. 运行单测或者benchmark Test的时候读取配置文件
  3. 可执行文件(部署文件)读取配置文件
  4. 项目中需要仅使用一个配置文件,配置文件可以在以上三种情况下都可以被正常读取

配置文件的放置

一般配置文件会放在项目的根目录或者比较明显的位置,当然对于Golang我个人还是比较推荐放在项目的根目录, 当然放在其他目录也不是不可以,但可能比较麻烦。

怎么满足配置文件需要应对的几种场景?

  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)

一个开源项目

项目地址喜欢的话点个赞(star), 有问题的话可以提issue. 以联系我。

获取的方式如下

go get  github.com/winjeg/goconf
复制代码
go moduledep
  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.

此文如有转载,请勿修改原文内容.