Go - 打包静态文件-bin文件直接使用
=====================
Go - 打包静态文件-bin文件直接使用
=====================
一、前言
使用 Go 开发应用的时候,有时会遇到需要读取静态资源的情况。
- 比如:开发 Web 应用,程序需要加载模板文件生成输出的 HTML。在程序部署的时候,除了发布应用可执行文件外,还需要发布依赖的静态资源文件。这给发布过程添加了一些麻烦。
- 比如:项目中有一些静态模板需要渲染,然而这些模板又是固定的静态文件
如果不打包处理这种静态文件:发布单独挂载这种静态文件相对比较麻烦,就有人会想办法把静态资源文件打包进 Go 的程序文件中。
下面介绍两种打包方式:go-bindata、go:embed
二、go-bindata打包静态资源
go-bindata 将任何文件封装在一个 Go 语言的 Source Code 里面,文件数据在转换为原始字节时可以选择使用 gzip 压缩,同时提供了统一的接口,帮助获取原始的文件数据
2.1 安装
go get -u github.com/go-bindata/go-bindata/...
注意:go-bindata对go的版本不同是有不一样的安装方式:
在go的版本>=1.17时,使用如下命令进行安装go-bindata
go install -a -v github.com/go-bindata/go-bindata/...@latest
安装打包工具 go-bindata 到GOPATH/bin
中,输入下面的命令检查下是否安装成功:
go-bindata --version
2.2 打包
go-bindata -o="resource.go" -pkg=resource ./resource/...
-
将把
./resource
目录下的所有文件转换为Go代码,注意后面的… 代表讲该文件下面所有的文件及子文件打包 -
生成一个名为
resource.go
的文件,你可以在你的Go代码中通过main
包来访问这些静态文件。
如果你查看源文件,可以查看 _bindata
中维护了文件的信息
2.3 使用
- Asset(name string) ([]byte, error) :根据资源名称返回文件内容
- MustAsset(name string) []byte :根据资源名称返回文件内容
- AssetInfo(name string) (os.FileInfo, error) : 根据资源名称返回文件信息
- AssetNames() []string :返回所有的资源名称
- AssetDir(name string) ([]string, error) : 返回某一个文件夹一层的名称
- RestoreAsset(dir, name string) error
- RestoreAssets(dir, name string) error
三、go:embed 打包静态资源
Go 1.16版本开始,可以使用go:embed来嵌入文件。
embed是在Go 1.16中新加包。它通过//go:embed
指令,可以在编译阶段将静态资源文件打包进编译好的程序(exe)中,并提供访问这些文件的能力。
- 对于单个的文件,支持嵌入类型为
string
和byte slice
- 对于多个文件和文件夹,支持嵌入为新的文件系统FS
- 比如导入
"embed"
包,即使无显式的使用
- go:embed指令用来嵌入,必须紧跟着嵌入后的变量名
注意:go embed的使用只能用于包级别声明的变量(全局变量
)
3.1 embed 要嵌入的文件
//go:embed 要嵌入的文件
- 示例一
import (
_ "embed"
"fmt"
)
//go:embed repos.tmpl
var data string
func main() {
fmt.Println(data)
}
- 示例二
import (
_ "embed"
"fmt"
)
//go:embed repos.tmpl
var data []byte
func main() {
fmt.Println(string(data))
}
3.2 嵌入文件系统FS
对于多个文件和文件夹,支持嵌入为新的文件系统FS
embed.FS提供了三个方法进行访问:
Open(name string) (fs.File, error) 根据资源key返回文件
ReadFile(name string) ([]byte, error) 根据资源key返回文件内容
ReadDir(name string) ([]fs.DirEntry, error) 根据key读取文件夹
- 嵌入文件夹
使用embed.FS
嵌入的文件变量,具有3种功能,如下所示:
import (
"embed"
_ "embed"
"fmt"
)
//go:embed resource
var data embed.FS
func main() {
// 直接读取文件
file, err := data.ReadFile("resource/cmd/main.go.tmpl")
fmt.Println(string(file), err)
}
- 嵌入多个文件
import (
"embed"
_ "embed"
"fmt"
)
//go:embed aa.text bb.text
var data embed.FS
func main() {
file, err := data.ReadFile("aa.text")
fmt.Println(string(file), err)
}
四、链接
-
studygolang.com/articles/30…
原文链接: https://juejin.cn/post/7359833949168353306
文章收集整理于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除,如若转载,请注明出处:http://www.cxyroad.com/17316.html