<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          go-embedxgo embed 的功能擴展

          聯(lián)合創(chuàng)作 · 2023-09-30 19:32

          go1.16 //go:embed 的功能擴展。

          簡介:

          go1.16 官方推出了go:embed 這個非常有意思的功能,可以嵌入靜態(tài)文件到一個可執(zhí)行文件中,發(fā)布軟件時,只需要發(fā)布軟件的可執(zhí)行程序就可以了,不需要另外發(fā)布那些靜態(tài)文件。之前這部分功能需要三方腳手架處理,比如go-bindata,go1.16開始,直接在go的工具鏈中提供了go:embed支持完成相同的工作,使用體驗非常的nice。

          具體使用示例可以參考tl-explorer:

          %> git clone --recursive https://github.com/alimy/tl-explorer
          %> cd tl-explorer && pwd
          go/src/github.com/alimy/tl-explorer
          
          %> tree -L 2
          .
          ├── Dockerfile
          ├── LICENSE
          ├── Makefile
          ├── README.md
          ├── assets
          │   ├── assets.go
          │   └── schema.tl
          ├── go.mod
          ├── go.sum
          ├── main.go
          └── scripts
              ├── launchd
              └── systemd
          
          

          該項目需要的靜態(tài)文件存放在assets/schema.tl 目錄中,需要把這個目錄的所有文件都嵌入到最終的可執(zhí)行程序中,可以這樣做(assets/assets.go):

          // Copyright 2020 Michael Li <[email protected]>. All rights reserved.
          // Use of this source code is governed by Apache License 2.0 that
          // can be found in the LICENSE file.
          
          package assets
          
          import (
          	"embed"
          	"net/http"
          
          	"github.com/alimy/embedx"
          )
          
          // NewFileSystem get an assets http.FileSystem instance
          func NewFileSystem() http.FileSystem {
          	//go:embed schema.tl
          	var content embed.FS
          
          	embedFS := embedx.ChangeRoot(content, "schema.tl")
          	return http.FS(embedFS)
          }

          聲明需要嵌入的那些文件,然后在程序中就可以通過embed.FS訪問這些文件,如例子中:

          	//go:embed schema.tl
          	var content embed.FS

          通過embed.FS訪問schema.tl中的文件。

          我們這里通過http server訪問schema.tl目錄中的靜態(tài)文件(main.go):

          // Copyright 2020 Michael Li <[email protected]>. All rights reserved.
          // Use of this source code is governed by Apache License 2.0 that
          // can be found in the LICENSE file.
          
          package main
          
          import (
          	"flag"
          	"fmt"
          	"log"
          	"net/http"
          
          	"github.com/alimy/tl-explorer/assets"
          )
          
          var (
          	host        string
          	port        uint
          	showVersion bool
          
          	version = "v0.2.0"
          )
          
          func init() {
          	flag.StringVar(&host, "host", "", "listening host")
          	flag.UintVar(&port, "port", 8080, "listening port")
          	flag.BoolVar(&showVersion, "v", false, "show version")
          }
          
          func main() {
          	flag.Parse()
          
          	if showVersion {
          		fmt.Println(version)
          		return
          	}
          	addr := fmt.Sprintf("%s:%d", host, port)
          	if host == "" {
          		host = "localhost"
          	}
          	fmt.Printf("listening in [%s]. Please open http://%s:%d in browser to enjoy yourself.\n", addr, host, port)
          
          	http.Handle("/", http.FileServer(assets.NewFileSystem()))
          	if err := http.ListenAndServe(addr, nil); err != nil {
          		log.Fatal(err)
          	}
          }
          

          官方的go:embed使用體驗非常好,那有沒有其他限制呢?有的,比如上面例子,我們嵌入了schema.tl目錄,那么通過embed.FS 訪問schema.tl目錄下的文件比如index.html時,需要這樣訪問:

          //go:embed schema.tl
          var content embed.FS
          
          indexContent, _ := content.ReadFile("schema.tl/index.html")

          我其實是想把schema.tl目錄作為根目錄,訪問目錄下的文件時,就如當前就在根目錄下訪問文件,不需要加schema.tl目錄名前綴:

          //go:embed schema.tl
          var content embed.FS
          
          // 預(yù)想schema.tl為根目錄, 訪問shema.tl/index.html, 只給定文件名index.html即可
          // indexContent, _ := content.ReadFile("index.html")

          go-embedx提供這樣的輔助功能特性,這里可以使用輔助庫的 ‘改變root目錄’ 功能,使用如下:

          //go:embed schema.tl
          var content embed.FS
          
          // 改變根目錄為shema.tl目錄
          embedFS := embedx.ChangeRoot(content, "schema.tl")
          
          // 訪問schema.tl目錄下的index.html,可以這樣做
          indexContent, _ := embedFS.ReadFile("index.html")
          fmt.Println(indexContent)

          go-embedx還提供其他輔助功能,比如為embed.FS 附加一個虛擬根目錄等。

          使用實例:

          %> cd demo # change to your golang project root directory; cd <your-project-dir>
          %> go get github.com/alimy/embedx
          %> tree
           |- public
              |- ...
              |- index.html
              |- ...
           |- conf
              |- app.ini
              |- ...
              |- conf.go
           |- ...
           |- main.go
           |- go.mod
           |- ...
          
          
          %> cat conf/conf.go
          // file: conf/conf.go
          
          package conf
          
          import (
          	"embed"
          	
          	"github.com/alimy/embedx"
          )
          
          func NewConfigFS() embedx.EmbedFS {
          	//go:embed app.ini
          	var content embed.FS
          
          	// attach a root to conf dir then access files in this returned FS will
          	// need add  'conf' prefix. eg: access app.ini need FS.ReadFile("conf/app.ini").
          	return embedx.AttachRoot(content, "conf")
          }
          
          
          %> cat main.go
          // file: main.go
          
          package main
          
          import (
          	"embed"
          	
          	"github.com/alimy/embedx"
          )
          
          func newPublicFS() embedx.EmbedFS {
          	//go:embed public
          	var content embed.FS
          	
          	// change the root to public dir then access files in this returned FS will
          	// not need  'public' prefix. eg: access public/index.html just need FS.ReadFile("index.html").
          	return embedx.ChangeRoot(content, "public")
          }
          ```

           

          瀏覽 16
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          編輯 分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          編輯 分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美精品久久久久 | 国内操逼视频 | 经典三级先锋影音 | 欧美一级 片内射欧美AA99 | 国产爱视频 |