我基本上试图浏览一个html文件夹。我想将它们嵌入到二进制文件中,并能够根据模板执行目的请求解析它们。 (如果我没有正确措辞,请原谅我。)
非常感谢任何想法,提示,技巧或更好的实现方法。
// Template Files
type TempFiles struct {
Files map[string]string
}
// Loop through view files and load them
func LoadTempFiles() {
t := new(TempFiles)
// Load template files
filepath.Walk("application/views", func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
content, _ := ioutil.ReadFile(path)
t.Files[path] = string(content)
}
return nil
})
}
func ViewTemp(w http.ResponseWriter, path string) {
t := new(TempFiles)
temp, err := template.New().Parse(t.Files[path])
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
} else {
temp.Execute(w, nil)
}
}
答案 0 :(得分:48)
我使用大多数Go网络应用程序执行此操作。我使用go-bindata从我想要嵌入的所有文件中自动生成Go源代码,然后将它们编译成二进制文件。 所有这些都是在构建期间自动完成的。
一个缺点是当前的go构建工具没有提供挂钩到构建过程的方法,所以我为此目的使用Makefile。调用makefile时,它运行go-bindata
以生成所有必需文件的源,然后通常执行一些额外的代码生成位和bobs(特别是创建一个Go源文件,其中列出了映射中的所有嵌入文件)。如果你愿意的话。然后它继续编译实际程序。
这可能会变得有点混乱,但你只需要设置一次。
另一个缺点是使用Makefile意味着该软件与go get
命令不兼容。但是,由于我的大多数网络应用程序都不打算共享,所以到目前为止这还不是问题。
在调试/开发此类应用程序时,嵌入静态Web内容还会产生另一个问题:我不能只编辑HTML或CSS文件并刷新浏览器以查看其效果。我必须停止服务器,重建它并在每次编辑时重新启动它。这显然不太理想,因此我将Makefile分成debug
和release
模式。释放模式执行我上面描述的操作。但是,调试模式实际上不会嵌入静态文件。它确实为每个文件生成源文件,但它不包含实际文件数据,而是包含一个简单地从文件系统加载数据的存根。
就服务器代码而言,生成的代码没有区别。它所做的只是调用一个函数来获取给定静态文件的内容。它不关心该内容是否实际嵌入在二进制文件中,或者是否从外部源加载。所以这两种构建模式可以自由互换。
例如,在发布和调试模式下获取静态文件内容的相同生成函数如下所示:
发布模式:
func index_html() []byte {
return []byte {
....
}
}
调试模式:
func index_html() []byte {
data, err := ioutil.ReadFile("index.html")
...
return data
}
两种情况下的界面都是相同的。这样可以轻松,轻松地进行开发和调试。
答案 1 :(得分:17)
另一个需要考虑的工具:另一个最近的好工具来自esc: Embedding Static Assets in Go(GitHub repo)
一个程序:
- 可以采用一些目录并以与http.FileSystem兼容的方式递归嵌入其中的所有文件
可以选择禁用- 以与本地文件系统一起使用以进行本地开发
- 不会在后续运行中更改输出文件
- 在文件更改时具有合理大小的差异
- 非常友好的
对供应友好意味着当我运行
godep
或派对时,静态嵌入文件不会更改。
这意味着它不能有任何第三方导入(因为它们的导入路径将在goimports
期间重写,因此与工具本身产生的不同),或者是所需第三方导入的可指定位置。 / p>它生成漂亮的,压缩的字符串,每个文件一个 有一个简单的标志可以启用本地开发模式,它足够智能,不会从文件名中删除目录前缀(
esc
中有时需要的选项)。
输出包括所有需要的代码,并且不依赖于任何第三方库以与http.FileSystem
兼容。
答案 2 :(得分:7)
我制作了一个软件包,可以更轻松地在调试和生产之间切换。它还提供了一个http.FileSystem实现,可以轻松地为文件提供服务。它有几种方法可以将文件添加到二进制文件中(生成转码或附加为zip)。 https://github.com/GeertJohan/go.rice
答案 3 :(得分:1)
Go 现在对此有内置支持:
package main
import (
"embed"
"os"
)
//go:embed *.html
var content embed.FS
func main() {
b, e := content.ReadFile("index.html")
if e != nil {
panic(e)
}
os.Stdout.Write(b)
}