内容纲要
前言
Go编译的程序非常适合部署,如果没有通过CGO引用其它的库的话,我们一般编译出来的可执行二进制文件都是单个的文件,非常适合复制和部署。在实际使用中,除了二进制文件,可能还需要一些配置文件,或者静态文件,比如html模板、静态的图片、CSS、javascript等文件,golang团队为此也制定了一个非常简易的api来将文件内嵌到其中。
嵌入特性
- 支持单文件嵌入为string和[]byte
- 支持将文件及文件夹嵌入为文件系统FS
- 隐式使用,匿名引入
embed
- 仅一行指令
go:embed
实现嵌入
嵌入示例
go将文件嵌入后是打包在编译出的二进制文件中的,所以文件仅支持读取和遍历,这也意味着它是线程安全的
以下为嵌入使用示例,
嵌入为string
比如当前文件下有个hello.txt的文件,文件内容为hello,world!。通过 go:embed
指令,在编译后下面程序中的s变量的值就变为了hello,world!。
package main
import (
_ "embed"
"fmt"
)
//go:embed hello.txt
var s string
func main() {
fmt.Println(s)
}
嵌入为[]byte
这里不多赘述,参见下面:
package main
import (
_ "embed"
"fmt"
)
//go:embed hello.txt
var b []byte
func main() {
fmt.Println(b)
}
嵌入为fs.FS
go提供了这个包来将文件内嵌为一个fs文件系统,专为嵌入文件夹所用!
package main
import (
"embed"
"fmt"
)
# 嵌入多个文件、子文件、文件夹
//go:embed hello.txt
//go:embed hello2.txt
//go:embed p/hello2.txt
//go:embed p
# 以上也可以写成一行,如 //go:embed hello.txt hello2.txt
var f embed.FS
func main() {
data, _ := f.ReadFile("hello.txt")
fmt.Println(string(data))
#读取文件夹中文件
data, _ := f.ReadFile("p/hello.txt")
fmt.Println(string(data))
data, _ = f.ReadFile("p/hello2.txt")
fmt.Println(string(data))
}
注意
go:embed
指令中可以只写文件夹名,此文件夹中除了.和_开头的文件和文件夹都会被嵌入,并且子文件夹也会被递归的嵌入,形成一个此文件夹的文件系统。
如果想嵌入.和_开头的文件和文件夹, 比如p文件夹下的.hello.txt文件,那么就需要使用*,比如go:embed p/*
。
不具有递归性,所以子文件夹下的.和_不会被嵌入,除非你在专门使用子文件夹的进行嵌入
template也可以从嵌入的文件系统中解析模板
发表评论