Golang 项目之配置文件

栏目: Go · 发布时间: 5年前

内容简介:相信对于很多gopher 而言, 我这篇文章,算比较初级,我是一个一年多经验的golang程序员,有着5年左右的编程经验。 golang 对于初学者还算友好, 写代码很好入门, 但业界对于golang工程与项目的BP却比较缺少,或者是有很多方为此争论不休,就比依赖管理工具就搞出了许多个,如 知名的有既然要说go项目的配置文件,那对于配置文件先做一个简单的介绍:yaml是最近很流行的一种描述语言,上手比较简单学习成本低,结构清晰, 5分钟即可掌握所有细节

相信对于很多gopher 而言, 我这篇文章,算比较初级,我是一个一年多经验的golang程序员,有着5年左右的编程经验。 golang 对于初学者还算友好, 写代码很好入门, 但业界对于golang工程与项目的BP却比较缺少,或者是有很多方为此争论不休,就比依赖管理 工具 就搞出了许多个,如 知名的有 dep , vgo 和golang 官方的 go 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 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. 找不到配置文件则会抛出错误,找到则不会返回任何错误

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

打破界限

打破界限

电通跨媒体开发项目组 / 苏友友 / 中信出版社 / 2011-10 / 35.00元

《打破界限:电通式跨媒体沟通策略》是日本电通跨媒体沟通开发项目组对“跨媒体”的思考方式、策划工具、成功案例和评估手段等诸多内容进行深入研究得到的丰硕成果,深刻剖析了此营销模式的本质。 目前,为客户提供整合式营销解决方案的电通模式在世界各国都获得了很高评价。而跨媒体沟通正是电通实现这种模式最先进的工具之一。一起来看看 《打破界限》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具