package main import ( "embed" "fmt" ) //go:embed hello.txt //go:embed hello2.txt var f embed.FS funcmain() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("hello2.txt") fmt.Println(string(data)) }
当前重复的go:embed指令嵌入为embed.FS是支持的,相当于一个:
1 2 3 4 5 6 7 8 9 10 11 12
package main import ( "embed" "fmt" ) //go:embed hello.txt //go:embed hello.txt var f embed.FS funcmain() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data)) }
还可以嵌入子文件夹下的文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
package main import ( "embed" "fmt" ) //go:embed p/hello.txt //go:embed p/hello2.txt var f embed.FS funcmain() { data, _ := f.ReadFile("p/hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("p/hello2.txt") fmt.Println(string(data)) }
同一个文件嵌入为多个变量
比如下面的例子,s和s2变量都嵌入hello.txt的文件。
1 2 3 4 5 6 7 8 9 10 11 12 13
package main import ( _ "embed" "fmt" ) //go:embed hello.txt var s string //go:embed hello.txt var s2 string funcmain() { fmt.Println(s) fmt.Println(s2) }
exported/unexported的变量都支持
Go可以将文件可以嵌入为exported的变量,也可以嵌入为unexported的变量。
1 2 3 4 5 6 7 8 9 10 11 12 13
package main import ( _ "embed" "fmt" ) //go:embed hello.txt var s string //go:embed hello2.txt var S string funcmain() { fmt.Println(s) fmt.Println(S) }
package级别的变量和局部变量都支持
前面的例子都是package一级的的变量,即使是函数内的局部变量,也都支持嵌入:
1 2 3 4 5 6 7 8 9 10 11 12
package main import ( _ "embed" "fmt" ) funcmain() { //go:embed hello.txt var s string //go:embed hello.txt var s2 string fmt.Println(s, s2) }
package main import ( "embed" "fmt" ) //go:embed p/* var f embed.FS funcmain() { data, _ := f.ReadFile("p/.hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile("p/q/.hi.txt") // 没有嵌入 p/q/.hi.txt fmt.Println(string(data)) }
嵌入和嵌入模式不支持绝对路径、不支持路径中包含.和..,如果想嵌入go源文件所在的路径,使用*:
1 2 3 4 5 6 7 8 9 10 11 12 13
package main import ( "embed" "fmt" ) //go:embed * var f embed.FS funcmain() { data, _ := f.ReadFile("hello.txt") fmt.Println(string(data)) data, _ = f.ReadFile(".hello.txt") fmt.Println(string(data)) }
文件系统
embed.FS实现了 io/fs.FS接口,它可以打开一个文件,返回fs.File:
1 2 3 4 5 6 7 8 9 10 11 12
package main import ( "embed" "fmt" ) //go:embed * var f embed.FS funcmain() { helloFile, _ := f.Open("hello.txt") stat, _ := helloFile.Stat() fmt.Println(stat.Name(), stat.Size()) }
它还提供了ReadFileh和ReadDir功能,遍历一个文件下的文件和文件夹信息:
1 2 3 4 5 6 7 8 9 10 11 12 13
package main import ( "embed" "fmt" ) //go:embed * var f embed.FS funcmain() { dirEntries, _ := f.ReadDir("p") for _, de := range dirEntries { fmt.Println(de.Name(), de.IsDir()) } }