Go打包靜態(tài)文件的兩種方式
一、前言
使用 Go 開發(fā)應用的時候,有時會遇到需要讀取靜態(tài)資源的情況。
比如:開發(fā) Web 應用,程序需要加載模板文件生成輸出的 HTML。在程序部署的時候,除了發(fā)布應用可執(zhí)行文件外,還需要發(fā)布依賴的靜態(tài)資源文件。這給發(fā)布過程添加了一些麻煩。
比如:項目中有一些靜態(tài)模板需要渲染,然而這些模板又是固定的靜態(tài)文件
如果不打包處理這種靜態(tài)文件:發(fā)布單獨掛載這種靜態(tài)文件相對比較麻煩,就有人會想辦法把靜態(tài)資源文件打包進 Go 的程序文件中。
下面介紹兩種打包方式:go-bindata、go:embed
二、go-bindata打包靜態(tài)資源
go-bindata 將任何文件封裝在一個 Go 語言的 Source Code 里面,文件數(shù)據(jù)在轉換為原始字節(jié)時可以選擇使用 gzip 壓縮,同時提供了統(tǒng)一的接口,幫助獲取原始的文件數(shù)據(jù)
2.1 安裝
go get -u github.com/go-bindata/go-bindata/...
安裝打包工具 go-bindata 到GOPATH/bin
中,輸入下面的命令檢查下是否安裝成功:
go-bindata --version
2.2 打包
go-bindata -o=resource.go -pkg=resource ./resource/...
- 將把
./resource
目錄下的所有文件轉換為Go代碼,注意后面的... 代表講該文件下面所有的文件及子文件打包
- 生成一個名為
resource.go
的文件,你可以在你的Go代碼中通過main
包來訪問這些靜態(tài)文件。
如果你查看源文件,可以查看 _bindata
中維護了文件的信息
2.3 使用
- Asset(name string) ([]byte, error) :根據(jù)資源名稱返回文件內(nèi)容
- MustAsset(name string) []byte :根據(jù)資源名稱返回文件內(nèi)容
- AssetInfo(name string) (os.FileInfo, error) : 根據(jù)資源名稱返回文件信息
- AssetNames() []string :返回所有的資源名稱
- AssetDir(name string) ([]string, error) : 返回某一個文件夾一層的名稱
- RestoreAsset(dir, name string) error
- RestoreAssets(dir, name string) error
三、go:embed 打包靜態(tài)資源
Go 1.16版本開始,可以使用go:embed來嵌入文件。
embed是在Go 1.16中新加包。它通過//go:embed
指令,可以在編譯階段將靜態(tài)資源文件打包進編譯好的程序(exe)中,并提供訪問這些文件的能力。
- 對于單個的文件,支持嵌入類型為
string
和byte slice
- 對于多個文件和文件夾,支持嵌入為新的文件系統(tǒng)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 嵌入文件系統(tǒng)FS
對于多個文件和文件夾,支持嵌入為新的文件系統(tǒng)FS
embed.FS提供了三個方法進行訪問:
Open(name string) (fs.File, error) 根據(jù)資源key返回文件 ? ReadFile(name string) ([]byte, error) 根據(jù)資源key返回文件內(nèi)容 ? ReadDir(name string) ([]fs.DirEntry, error) 根據(jù)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) }
到此這篇關于Go打包靜態(tài)文件的兩種方式的文章就介紹到這了,更多相關Go打包靜態(tài)文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!