golang嵌入文件以便以后解析执行使用

时间:2012-09-18 17:48:07

标签: go

我基本上试图浏览一个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)
    }
}

4 个答案:

答案 0 :(得分:48)

我使用大多数Go网络应用程序执行此操作。我使用go-bindata从我想要嵌入的所有文件中自动生成Go源代码,然后将它们编译成二进制文件。 所有这些都是在构建期间自动完成的。

一个缺点是当前的go构建工具没有提供挂钩到构建过程的方法,所以我为此目的使用Makefile。调用makefile时,它运行go-bindata以生成所有必需文件的源,然后通常执行一些额外的代码生成位和bobs(特别是创建一个Go源文件,其中列出了映射中的所有嵌入文件)。如果你愿意的话。然后它继续编译实际程序。

这可能会变得有点混乱,但你只需要设置一次。 另一个缺点是使用Makefile意味着该软件与go get命令不兼容。但是,由于我的大多数网络应用程序都不打算共享,所以到目前为止这还不是问题。

在调试/开发此类应用程序时,嵌入静态Web内容还会产生另一个问题:我不能只编辑HTML或CSS文件并刷新浏览器以查看其效果。我必须停止服务器,重建它并在每次编辑时重新启动它。这显然不太理想,因此我将Makefile分成debugrelease模式。释放模式执行我上面描述的操作。但是,调试模式实际上不会嵌入静态文件。它确实为每个文件生成源文件,但它不包含实际文件数据,而是包含一个简单地从文件系统加载数据的存根。

就服务器代码而言,生成的代码没有区别。它所做的只是调用一个函数来获取给定静态文件的内容。它不关心该内容是否实际嵌入在二进制文件中,或者是否从外部源加载。所以这两种构建模式可以自由互换。

例如,在发布和调试模式下获取静态文件内容的相同生成函数如下所示:

发布模式:

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 GoGitHub 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)
}

https://golang.org/pkg/embed