Go embed 代替 go-bindata | Go主题月

25,481 阅读1分钟

之前写过一篇关于使用 go-bindata 打包配置文件的文章:你不知道的 Golang 打包配置文件,但在 Go 1.16 中包含了 go embed 的功能,使用它可以代替 go-bindata 将文件嵌入到可执行的二进制文件中,本文将通过例子,详细介绍 go embed 的各个功能,主要包含:

  • 对于单个的文件,支持嵌入为 string[]byte
  • 对于多个文件和文件夹,支持嵌入为新的文件系统 embed.FS
  • 下划线导入 embed 包,调用包中的 init() 函数进行初始化
  • 使用 //go:embed 指令进行嵌入,后面加上嵌入的文件名或目录名
  • 只支持嵌入为 string[]byteembed.FS 三种类型

嵌入 string

基本语法非常简单,首先导入embed包,然后使用指令 //go:embed 文件名 将对应的文件或目录结构导入到对应的变量上。 例如:在当前目录下新建一个文件 version.txt,并输入内容 0.0.1:

package main

import (
    _ "embed"
    "fmt"
)

//go:embed version.txt
var version string

func main() {
    fmt.Printf("version: %q\n", version)
}

嵌入 []byte

package main

import (
    _ "embed"
    "fmt"
)

//go:embed version.txt
var vb []byte

func main() {
    fmt.Printf("version %q\n", string(vb))
}

嵌入 embed.FS

这个时候可以嵌入多个文件或者目录,嵌入多个文件的时候,go:embed 指令可以写成一行或者多行:

package main

import (
    _ "embed"
    "fmt"
)

//go:embed hello.txt world.txt
var f embed.FS

func main() {
    data, _ := f.ReadFile("hello.txt")
    fmt.Println(string(data))
}

embed.FS 类型主要有 3 个方法:

func (f FS) Open(name string) (fs.File, error)

func (f FS) ReadDir(name string) ([]fs.DirEntry, error)

func (f FS) ReadFile(name string) ([]byte, error)

总结

Go embed 确实好用呀,省得使用 go-bindata 生成额外的 go 源码文件了,点赞!