通常后端服务启动需要的配置文件,然而配置文件中包含了敏感信息,出于安全考虑,将配置文件直接编译到可以执行文件中。.toml,.json,.yaml等后缀的文件都可以打包,我使用的是.toml。根据业务需要来选择。原理都一样
操作步骤:
1. 安装go-bindata包
go get -u github.com/go-bindata/go-bindata/...
2. 查看是否安装成功
执行: go-bindata -help,出现如图,表示安装成功
3. 执行编译语句
go-bindata -pkg=tool -o=./tool/conf.go test.toml
-pkg : 表示目录名,目录名不存在会自动创建在当前目录下
-o:表示将配置文件生成的.go文件放到那个目录的那个文件下
test.toml: 要打包的配置文件
4. 代码示例,使用的配置文件如下
# test.toml文件内容示例 [general] listen="0.0.0.0:9090"
package main
import (
"bytes"
"fmt"
"github.com/spf13/viper"
)
func main(){
data, _ := Asset("test.toml")
fmt.Println(string(data))
conf(data)
fmt.Println("listen:",C.General.Listen)
}
var C Config
type Config struct {
General struct {
Listen string `mapstructure:"listen"`
}`mapstructure:"general"`
}
func conf(b []byte) {
if len(b) >= 0 {
viper.SetConfigType("toml")
if err := viper.ReadConfig(bytes.NewBuffer(b)); err != nil {
fmt.Println("error loading config file")
}
}
if err := viper.Unmarshal(&C); err != nil {
fmt.Println("error loading config file",err)
}
}
5. 生成的conf.go文件,我也直接贴出来吧
package main
import (
"bytes"
"compress/gzip"
"fmt"
"io"
"strings"
)
func bindata_read(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
gz.Close()
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
return buf.Bytes(), nil
}
var _test_toml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8a\x4e\x4f\xcd\x4b\x2d\x4a\xcc\x89\xe5\xe5\xca\xc9\x2c\x2e\x49\xcd\xb3\x55\x32\xd0\x03\x43\x2b\x4b\x03\x4b\x03\x25\x40\x00\x00\x00\xff\xff\x62\x15\x90\x2b\x20\x00\x00\x00")
func test_toml() ([]byte, error) {
return bindata_read(
_test_toml,
"test.toml",
)
}
// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
return f()
}
return nil, fmt.Errorf("Asset %s not found", name)
}
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
for name := range _bindata {
names = append(names, name)
}
return names
}
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() ([]byte, error){
"test.toml": test_toml,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
cannonicalName := strings.Replace(name, "\\", "/", -1)
pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
}
}
if node.Func != nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for name := range node.Children {
rv = append(rv, name)
}
return rv, nil
}
type _bintree_t struct {
Func func() ([]byte, error)
Children map[string]*_bintree_t
}
var _bintree = &_bintree_t{nil, map[string]*_bintree_t{
"test.toml": &_bintree_t{test_toml, map[string]*_bintree_t{
}},
}}