Go:在二进制中嵌入静态文件
Go: embed static files in binary
这可能是一个非常业余的问题。我正在尝试将静态文件嵌入到二进制文件中,即。 html。我如何用 https://github.com/jteeuwen/go-bindata 做到这一点?
因此我可以使用此 https://github.com/jteeuwen/go-bindata#accessing-an-asset 访问资产,但是我如何使用 "data" 以及如何解析文件、执行模板并在目录中提供它们?
我无法在网上找到任何示例,非常感谢您的帮助!
给定如下目录结构:
example/
main.go
data/hi.html
example/main.go
package main
import (
"html/template"
"log"
"net/http"
"os"
)
var tmpl *template.Template
func init() {
data, err := Asset("data/hi.html")
if err != nil {
log.Fatal(err)
}
tmpl = template.Must(template.New("tmpl").Parse(string(data)))
}
func main() {
// print to stdout
tmpl.Execute(os.Stdout, map[string]string{"Name": "James"})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
tmpl.Execute(w, map[string]string{"Name": "James"})
})
log.Fatal(http.ListenAndServe(":8000", nil))
}
example/data/hi.html
<h1>Hi, {{.Name}}</h1>
运行 像这样:
go-bindata data && go build && ./example
控制台输出:
<h1>Hi, James</h1>
HTTP 输出:
嗨,詹姆斯
5/6 年后,使用 Go 1.16(2021 年第一季度)这应该会更容易,它增加了对嵌入式文件的支持(issue/proposal 41191)
It will be permitted to use //go:embed
naming a single file to initialize a plain string
or []byte
variable:
//go:embed gopher.png
var gopherPNG []byte
导入需要将文件标记为包含 //go:embed
行并需要处理。
Goimports
(和 gopls
等)可以学习此规则,并根据需要自动将导入添加到带有 //go:embed
的任何文件中。
这引发了关于 issue 42328 的辩论,即如何在使用 //go:embed
时避免意外包含“隐藏”文件
这已在 CL 275092 and commit 37588ff
中解决
Decision to exclude files matching .*
and _*
from embedded directory results when embedding an entire directory tree.
见src/embed/internal/embedtest/embed_test.go
//go:embed testdata/k*.txt
var local embed.FS
testFiles(t, local, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/k*.txt
var s string
testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/h*.txt
var b []byte
testString(t, string(b), "local variable b", "hello, world\n")
注意:如果支持 CL 281492,cmd/go
会将 embedcfg
传递给 gccgo
。
另见(2021 年 1 月)issue 43854“选择 //go:embed
以 不 忽略文件和空目录”。
这可能是一个非常业余的问题。我正在尝试将静态文件嵌入到二进制文件中,即。 html。我如何用 https://github.com/jteeuwen/go-bindata 做到这一点?
因此我可以使用此 https://github.com/jteeuwen/go-bindata#accessing-an-asset 访问资产,但是我如何使用 "data" 以及如何解析文件、执行模板并在目录中提供它们?
我无法在网上找到任何示例,非常感谢您的帮助!
给定如下目录结构:
example/
main.go
data/hi.html
example/main.go
package main
import (
"html/template"
"log"
"net/http"
"os"
)
var tmpl *template.Template
func init() {
data, err := Asset("data/hi.html")
if err != nil {
log.Fatal(err)
}
tmpl = template.Must(template.New("tmpl").Parse(string(data)))
}
func main() {
// print to stdout
tmpl.Execute(os.Stdout, map[string]string{"Name": "James"})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
tmpl.Execute(w, map[string]string{"Name": "James"})
})
log.Fatal(http.ListenAndServe(":8000", nil))
}
example/data/hi.html
<h1>Hi, {{.Name}}</h1>
运行 像这样:
go-bindata data && go build && ./example
控制台输出:
<h1>Hi, James</h1>
HTTP 输出:
嗨,詹姆斯
5/6 年后,使用 Go 1.16(2021 年第一季度)这应该会更容易,它增加了对嵌入式文件的支持(issue/proposal 41191)
It will be permitted to use
//go:embed
naming a single file to initialize a plainstring
or[]byte
variable:
//go:embed gopher.png
var gopherPNG []byte
导入需要将文件标记为包含 //go:embed
行并需要处理。
Goimports
(和 gopls
等)可以学习此规则,并根据需要自动将导入添加到带有 //go:embed
的任何文件中。
这引发了关于 issue 42328 的辩论,即如何在使用 //go:embed
这已在 CL 275092 and commit 37588ff
中解决Decision to exclude files matching
.*
and_*
from embedded directory results when embedding an entire directory tree.
见src/embed/internal/embedtest/embed_test.go
//go:embed testdata/k*.txt
var local embed.FS
testFiles(t, local, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/k*.txt
var s string
testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/h*.txt
var b []byte
testString(t, string(b), "local variable b", "hello, world\n")
注意:如果支持 CL 281492,cmd/go
会将 embedcfg
传递给 gccgo
。
另见(2021 年 1 月)issue 43854“选择 //go:embed
以 不 忽略文件和空目录”。