久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      embed是啥?Go怎么用它加載靜態(tài)文件?

      本文由go語言教程欄目給大家介紹Golang1.16怎么使用embed加載靜態(tài)文件 ,希望對需要的朋友有所幫助!

      embed是什么

      embed是在Go 1.16中新加入的包。它通過//go:embed指令,可以在編譯階段將靜態(tài)資源文件打包進(jìn)編譯好的程序中,并提供訪問這些文件的能力。

      為什么需要embed

      在以前,很多從其他語言轉(zhuǎn)過來Go語言的小伙伴會問到,或者踩到一個坑:就是以為Go語言所打包的二進(jìn)制文件中會包含配置文件的聯(lián)同編譯和打包。

      結(jié)果往往一把二進(jìn)制文件挪來挪去,就無法把應(yīng)用程序運行起來了,因為無法讀取到靜態(tài)文件的資源。

      無法將靜態(tài)資源編譯打包二進(jìn)制文件的話,通常會有兩種解決方法:

      • 第一種是識別這類靜態(tài)資源,是否需要跟著程序走。
      • 第二種就是將其打包進(jìn)二進(jìn)制文件中。

      第二種情況的話,Go以前是不支持的,大家就會借助各種花式的開源庫,例如:go-bindata/go-bindata來實現(xiàn)。

      但是在Go1.16起,Go語言自身正式支持了該項特性。

      它有以下優(yōu)點

      • 能夠?qū)㈧o態(tài)資源打包到二進(jìn)制包中,部署過程更簡單。傳統(tǒng)部署要么需要將靜態(tài)資源與已編譯程序打包在一起上傳,或者使用dockerdockerfile自動化前者,這是很麻煩的。
      • 確保程序的完整性。在運行過程中損壞或丟失靜態(tài)資源通常會影響程序的正常運行。
      • 靜態(tài)資源訪問沒有io操作,速度會非???/strong>。

      embed基礎(chǔ)用法

      通過 官方文檔 我們知道embed嵌入的三種方式:string、bytes 和 FS(File Systems)。其中string[]byte類型都只能匹配一個文件,如果要匹配多個文件或者一個目錄,就要使用embed.FS類型。

      特別注意:embed這個包一定要導(dǎo)入,如果導(dǎo)入不使用的話,使用 _ 導(dǎo)入即可

      一、嵌入為字符串


      比如當(dāng)前文件下有個hello.txt的文件,文件內(nèi)容為hello,world!。通過go:embed指令,在編譯后下面程序中的s變量的值就變?yōu)榱?code>hello,world!。

      package mainimport (     _ "embed"     "fmt")//go:embed hello.txtvar s stringfunc main() {     fmt.Println(s)}

      二、嵌入為byte slice


      你還可以把單個文件的內(nèi)容嵌入為slice of byte,也就是一個字節(jié)數(shù)組。

      package mainimport (     _ "embed"     "fmt")//go:embed hello.txtvar b []bytefunc main() {     fmt.Println(b)}

      三、嵌入為fs.FS


      甚至你可以嵌入為一個文件系統(tǒng),這在嵌入多個文件的時候非常有用。

      比如嵌入一個文件:

      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))}

      當(dāng)前重復(fù)的go:embed指令嵌入為embed.FS是支持的,相當(dāng)于一個:

      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進(jìn)階用法

      Go1.16 為了對 embed 的支持也添加了一個新包 io/fs。兩者結(jié)合起來可以像之前操作普通文件一樣。

      一、只讀

      嵌入的內(nèi)容是只讀的。也就是在編譯期嵌入文件的內(nèi)容是什么,那么在運行時的內(nèi)容也就是什么。

      FS文件系統(tǒng)值提供了打開和讀取的方法,并沒有write的方法,也就是說FS實例是線程安全的,多個goroutine可以并發(fā)使用。

      embed.FS結(jié)構(gòu)主要有3個對外方法,如下:

      // Open 打開要讀取的文件,并返回文件的fs.File結(jié)構(gòu).func (f FS) Open(name string) (fs.File, error)// ReadDir 讀取并返回整個命名目錄func (f FS) ReadDir(name string) ([]fs.DirEntry, error)// ReadFile 讀取并返回name文件的內(nèi)容.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))}

      當(dāng)然你也可以像前面的例子一樣寫成多行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系統(tǒng)也采用這個模式。

      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))}

      應(yīng)用

      在我們的項目中,是將應(yīng)用的常用的一些配置寫在了.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)}

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號