问题描述
我本质上是试图浏览一个html文件的文件夹。我想将它们嵌入到二进制文件中,并且可以根据模板执行的要求解析它们。 (请原谅,如果我没有适当的措辞)。任何想法,技巧,窍门或更好的方式来实现这一点非常赞赏。 b
//模板文件
类型TempFiles结构{
文件map [string] string
}
//遍历视图文件并加载它们
func LoadTempFiles(){
t:= new(TempFiles)
//载入模板文件
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,路径字符串){
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)
}
}
我使用我的大部分Go网络应用程序进行此操作。我使用从所有想要嵌入的文件自动生成Go源代码,然后将它们编译成二进制文件。
所有这些都是在构建过程中自动完成的。
一个缺点是当前的构建工具没有提供钩入构建过程的方法,所以我为此使用Makefile。当makefile被调用时,它会运行 go-bindata
来生成所有必需文件的源代码,然后通常执行一些额外的代码生成位和bobs(特别是创建一个Go源代码文件,其中列出了地图中的所有嵌入文件。如果您愿意,可以列出目录)。然后继续编译实际的程序。
这可能会变得有点混乱,但您只需将其全部设置一次即可。
另一个缺点是使用Makefile意味着软件与 go get
命令不兼容。但是,由于我的大多数网络应用程序并不意味着无法共享,所以迄今为止这并不是问题。
在调试/开发这样的应用程序时,嵌入静态网页内容还有另一个问题:我不能只编辑HTML或CSS文件并刷新浏览器以查看其效果。我将不得不停止服务器,重建它并在每次编辑时重新启动它。这显然不理想,所以我将Makefile分成了 debug
和 release
模式。发布模式就是我上面描述的。然而,调试模式实际上并没有嵌入静态文件。它确实为每个文件生成源文件,但它们不包含实际的文件数据,而是包含一个存根,它只是从文件系统加载数据。
就服务器代码而言,生成的代码没有区别。它所做的只是调用一个函数来获取给定静态文件的内容。它并不关心这些内容是否实际嵌入到二进制文件中,或者是否从外部源加载。因此,这两种构建模式可以自由互换。例如,在释放和调试模式下获取静态文件内容的相同生成函数如下所示:
发布模式:
func index_html()[] byte {
返回[]字节{
....
}
}
$ b $ pre $ func index_html()[] byte {
data,err:= ioutil.ReadFile( index.html)
...
返回数据
}
两种情况下的界面都是相同的。这使得开发和调试变得简单和轻松。
I am essentially trying to walk through a folder of html files. I want to embed them into the binary file and be able to parse them upon request for template execution purposes. (Please excuse me if im not wording this properly).
Any ideas, tips, tricks or better way of accomplishing this is much appreciated.
// 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)
}
}
I do this with most of my Go web apps. I use go-bindata to auto-generate Go source code from all the files I want to embed and then compile them into the binary.All this is done automatically during build.
One downside is that the current go build tools do not offer a way to hook into the build process, so I use a Makefile for this purpose. When the makefile is invoked, it runs go-bindata
to generate the sources for all necessary files, then usually performs some additional code generation bits and bobs (notably, creating a Go source file which lists all the embedded files in a map.. A Table of Contents if you will). It then proceeds to compile the actual program.
This can become a little messy, but you only have to set it all up once.Another downside, is that the use of a Makefile means the software is not compatible with the go get
command. But since most of my web apps are not meant to be shared anyway, this has not been a problem so far.
When it comes to debugging/developing such an application, there is another issue that arises from embedding the static web content: I can't just edit an HTML or CSS file and refresh the browser to see its effects. I would have to stop the server, rebuild it and restart it with every edit. This is obviously not ideal, so I split the Makefile up into a debug
and release
mode. The release mode does what I described above. The debug mode, however, wil not actually embed the static files. It does generate source files for each of them, but instead of having them contain the actual file data, it contains a stub which simply loads the data from the filesystem.
As far as the server code is concerned, there is no difference in the generated code. All it does is call a function to fetch the contents of a given static file. It does not care whether that content is actually embedded in the binary, or if it's loaded from an external source. So the two build modes are freely interchangeable.
For example, the same generated function to fetch static file content in release and debug mode would look as follows:
Release mode:
func index_html() []byte {
return []byte {
....
}
}
Debug mode:
func index_html() []byte {
data, err := ioutil.ReadFile("index.html")
...
return data
}
The interface in both cases is identical. This allows for easy and care-free development and debugging.
这篇关于golang嵌入文件供以后解析执行使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!