本文由go語言教學欄位來介紹Golang1.16怎麼使用embed載入靜態檔案 ,希望對需要的朋友有幫助!
##embed是什麼
embed是Go 1.16中新加入的套件。它透過//go:embed指令,可以在編譯階段將靜態資源檔案打包進編譯好的程式中,並提供存取這些檔案的能力。
為什麼需要embed
在以前,很多從其他語言轉過來Go語言的小夥伴會問到,或是踩到一個坑:就是以為Go語言所打包的二進位檔案中會包含設定檔的聯同編譯和打包。 結果往往一把二進位檔案挪來挪去,就無法把應用程式運作起來了,因為無法讀取到靜態檔案的資源。 無法將靜態資源編譯打包二進位檔案的話,通常會有兩種解決方法:go-bindata/go-bindata來實現。
和
dockerfile自動化前者,這是很麻煩的。
string和
[]byte類型都只能匹配一個文件,如果要匹配多個文件或一個目錄,就要使用
embed.FS類型。
特別注意:embed這個套件一定要導入,如果導入不使用的話,使用_ 導入即可
hello,world!。透過
go:embed指令,在編譯後下面程式中的s變數的值就變成了
hello,world!。
package mainimport ( _ "embed" "fmt")//go:embed hello.txtvar s stringfunc main() { fmt.Println(s)}
package mainimport ( _ "embed" "fmt")//go:embed hello.txtvar b []bytefunc main() { fmt.Println(b)}
package mainimport ( "embed" "fmt")//go:embed hello.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data))}嵌入本地的另一個檔案hello2.txt, 支援同一個變數上多個
go:embed指令(嵌入為string或者byte slice是不能有多個
go:embed指令的):
package mainimport ( "embed" "fmt")//go:embed hello.txt//go:embed hello2.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("hello2.txt") fmt.Println(string(data))}目前重複的
go:embed指令嵌入為embed.FS是支援的,相當於一個:
package mainimport ( "embed" "fmt")//go:embed hello.txt//go:embed hello.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data))}還可以嵌入子資料夾下的檔案:
package mainimport ( "embed" "fmt")//go:embed p/hello.txt//go:embed p/hello2.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("p/hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("p/hello2.txt") fmt.Println(string(data))}
embed 的支援也新增了一個新套件
io/fs。兩者結合起來可以像之前操作普通文件一樣。
// Open 打开要读取的文件,并返回文件的fs.File结构.func (f FS) Open(name string) (fs.File, error)// ReadDir 读取并返回整个命名目录func (f FS) ReadDir(name string) ([]fs.DirEntry, error)// ReadFile 读取并返回name文件的内容.func (f FS) ReadFile(name string) ([]byte, error)
package mainimport ( "embed" "fmt")//go:embed hello.txt hello2.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("hello2.txt") fmt.Println(string(data))}
go:embed:
package mainimport ( "embed" "fmt")//go:embed hello.txt//go:embed hello2.txtvar f embed.FSfunc main() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("hello2.txt") fmt.Println(string(data))}
/,即使是windows系統也採用此模式。
package mainimport ( "embed" "fmt")//go:embed pvar f embed.FSfunc main() { data, _ := f.ReadFile("p/hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("p/hello2.txt") fmt.Println(string(data))}
在我们的项目中,是将应用的常用的一些配置写在了.env的一个文件上,所以我们在这里就可以使用go:embed
指令。
main.go
文件:
//go:embed ".env" "v1d0/.env"var FS embed.FSfunc main(){ setting.InitSetting(FS) manager.InitManager() cron.InitCron() routersInit := routers.InitRouter() readTimeout := setting.ServerSetting.ReadTimeout writeTimeout := setting.ServerSetting.WriteTimeout endPoint := fmt.Sprintf(":%d", setting.ServerSetting.HttpPort) maxHeaderBytes := 1 << 20 server := &http.Server{ Addr: endPoint, Handler: routersInit, ReadTimeout: readTimeout, WriteTimeout: writeTimeout, MaxHeaderBytes: maxHeaderBytes, } server.ListenAndServe()}
setting.go
文件:
func InitSetting(FS embed.FS) { // 总配置处理 var err error data, err := FS.ReadFile(".env") if err != nil { log.Fatalf("Fail to parse '.env': %v", err) } cfg, err = ini.Load(data) if err != nil { log.Fatal(err) } mapTo("server", ServerSetting) ServerSetting.ReadTimeout = ServerSetting.ReadTimeout * time.Second ServerSetting.WriteTimeout = ServerSetting.WriteTimeout * time.Second // 分版本配置引入 v1d0Setting.InitSetting(FS)}
以上是embed是啥? Go怎麼用它載入靜態檔案?的詳細內容。更多資訊請關注PHP中文網其他相關文章!