编写工具的时候往往需要依赖一些配置文件、模板文件等静态资源,但编译成可执行文件后仍然需要读取相关资源,这样就导致本身是为了方便的二进制文件还需要一堆配置模板文件才能正常运行,反而不太方便了。
go 1.16 新增了 //go:embed
指令,可以使用 go doc embed
查看说明文档。下面举一个读取配置文件、模板的案例。
导入 embed,读取配置文件使用 viper。
1 2 3 4 5 6 7
| import ( "bytes" _ "embed" "fmt"
"github.com/spf13/viper" )
|
使用 embed 包嵌入配置文件,这里的 //go:embed config.yaml
并不是注释。
1 2 3 4 5
| var embeddedConfig []byte
var embeddedTemplate []byte
|
定义配置文件结构体。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| type API struct { Ks string `yaml:"KS"` }
type SET struct { User string `yaml:"User"` TempDir string `yaml:"TempDir"` DescDir string `yaml:"DescDir"` }
type Config struct { Api API Set SET }
|
编写一个函数用来解析文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| func ReadConfig() (*Config, error) { viper.SetConfigType("yaml") err := viper.ReadConfig(bytes.NewBuffer(embeddedConfig)) if err != nil { return nil, fmt.Errorf("error reading embedded config: %w", err) } var config Config err = viper.Unmarshal(&config) if err != nil { return nil, fmt.Errorf("error unmarshaling config: %w", err) } return &config, nil }
|
读取扫描模板
1 2 3 4 5 6 7
| func ReadTemplateContent() (string, error) { if len(embeddedTemplate) == 0 { return "", fmt.Errorf("扫描模板文件为空或未嵌入") } return string(embeddedTemplate), nil }
|
此时使用 ReadConfig
获取 Config 结构体,使用 ReadTemplateContent
读取 tem.yaml
的文件内容。编译后的二进制文件,就可以不依赖静态文件也可以运行。