我们都知道,go编译的程序非常适合部署
我们一般编译出来的可执行二进制文件都是单个的文件,非常适合复制和部署
还能通过交叉编译在windows上开发编译到linux平台使用
简直不要太爽
但是我们在项目中可能还会用到静态文件,这些是不会编译到二进制程序中去的
例如项目的配置文件
例如项目运行中需要读取的文件
如果这些文件也可以被打包到二进制文件里面,那就太美妙了,编译之后直接一个可执行文件即可搞定
嵌入
- 对于单个的文件,支持嵌入为字符串和 byte slice
- 对于多个文件和文件夹,支持嵌入为新的文件系统FS
- 比如导入 "embed"包,即使无显式的使用
go:embed
指令用来嵌入,必须紧跟着嵌入后的变量名- 只支持嵌入为string, byte slice和embed.FS三种类型,这三种类型的别名(alias)和命名类型(如type S string)都不可以
嵌入字符串
package main
import (
_ "embed"
"fmt"
)
//go:embed hello.txt
var data string
func main() {
fmt.Println(data)
}
嵌入byte slice
package main
import (
_ "embed"
"fmt"
)
//go:embed hello.txt
var data []byte
func main() {
fmt.Println(string(data))
}
嵌入embed.FS
嵌入单个文件
package main
import (
"embed"
_ "embed"
"fmt"
)
//go:embed hello.txt
var fs embed.FS
func main() {
byteData, err := fs.ReadFile("hello.txt")
fmt.Println(string(byteData), err)
}
嵌入多个文件
package main
import (
"embed"
_ "embed"
"fmt"
)
//go:embed hello.txt jwt.go
var fs embed.FS
func main() {
byteData, err := fs.ReadFile("hello.txt")
fmt.Println(string(byteData), err)
byteData, err = fs.ReadFile("jwt.go")
fmt.Println(string(byteData), err)
}
嵌入一个目录
package main
import (
"embed"
_ "embed"
"fmt"
"path"
)
//go:embed proxy
var fs embed.FS
func main() {
dir, err := fs.ReadDir("proxy")
if err != nil {
fmt.Println(err)
return
}
for _, entry := range dir {
info, _ := entry.Info()
fmt.Println(info.Name())
if info.IsDir() {
subDir, _ := fs.ReadDir(path.Join("proxy", info.Name()))
for _, subEntry := range subDir {
subInfo, _ := subEntry.Info()
fmt.Printf(" -%s\n", subInfo.Name())
}
}
}
}
注意:go:embed只能用于包级别声明的变量,在函数里面是不能用的
实际应用
有些场合,我们在程序里面会读取一些静态文件,这些静态文件开发好之后就八辈子不会再变了
并且文件也不大
不把它编译到程序里面,到时候部署还得把这个文件移过去移过来,麻烦
例如我的项目,我单独把es的索引写在了json文件里面
func (CdnLogModelEs) Mapping() string {
byteData, err := os.ReadFile("models/cdn_log_model_mapping.json")
if err != nil {
logrus.Error(err)
panic(err)
return ""
return string(byteData)
}
这是之前的写法,只要服务器上要重建索引的适合,必须要把这个json文件给带上去,还是很麻烦的
所以现在的写法就很方便了
//go:embed cdn_log_model_mapping.json
var cdnLogModelMapping string
func (CdnLogModelEs) Mapping() string {
return cdnLogModelMapping
}
不适合嵌入
- 大文件
- 经常变化的文件(例如配置文件)
参考文档
embed简明教程 Go embed 简明教程-CSDN博客
标签:嵌入,string,err,fmt,ebmed,go,embed From: https://blog.csdn.net/csdngzy/article/details/143038944