Golang Go语言中 embed 小技巧-动态文件更新

Golang Go语言中 embed 小技巧-动态文件更新

go1.16 embed 可以将文件嵌入到编译后的二进制中,以后发布一个 web 程序可以只提供一个二进制程序,不需要其他文件,同时避免重复文件 io 读取。

但是在开发时,使用 embed 后如果修改前端文件那么需要重启 GO 程序,重新生成 embed 数据,导致开发过程不方便。

提供一个 embed 支持动态文件的小技巧,使用 http.Dir 和 embed.FS 混合组合一个新的 http.FileSystem,如果当前目录存在静态文件,那么使用 http.Dir 返回静态文件内容,否则使用 embed.FS 编译的内容,这样既可以使用 http.Dir 访问时时的静态文件,可以使发布的二进制程序使用 embed.FS 编译内置的静态文件数据。

package main

import ( “embed” “net/http” )

//go:embed static var f embed.FS

func main() { http.ListenAndServe(":8088", http.FileServer(FileSystems{ http.Dir("."), http.FS(f), })) }

// 组合多个 http.FileSystem type FileSystems []http.FileSystem

func (fs FileSystems) Open(name string) (file http.File, err error) { for _, i := range fs { // 依次打开多个 http.FileSystem 返回一个成功打开的数据。 file, err = i.Open(name) if err == nil { return } } return }

在代码目录创建一个 static 目录,然后里面创建一个 index.html auth.html,启动程序后就可以使用 http://localhost:8088/static/index.html 访问到静态文件,在修改文件后不重启也会显示最新的文件内容。


更多关于Golang Go语言中 embed 小技巧-动态文件更新的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

更多关于Golang Go语言中 embed 小技巧-动态文件更新的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我还在等 brew 发 1.16 呢……

可以使用 gvm,已经用上 1.6 了。

typo: 1.6 -> 1.16

懒得搞,golang 兼容性还行,一直用最新版…java 和 node 倒是用了版本管理

哈哈,我也在等,天天在看状态
https://github.com/Homebrew/homebrew-core/pull/71289

最后一个前置修改刚刚已经 merge 了,现在正在跑 Test,应该马上就会合并了

nice idea, 顺便问一下楼主那边,后端 host 一个静态文件服务器的应用场景是什么样的?

在Go语言中,embed 包是 Go 1.16 版本引入的一个非常有用的特性,它允许开发者将静态文件(如模板、配置文件、静态资源等)直接嵌入到编译后的二进制文件中。虽然 embed 包主要设计用于嵌入静态资源,但实现动态文件更新的需求可以通过一些技巧来实现。

  1. 配置文件热更新: 对于配置文件,可以通过监听文件系统的变化(如使用 fsnotify 包)来实现热更新。当检测到配置文件变化时,重新读取并应用新的配置。虽然文件本身没有直接嵌入,但这种方法可以实现类似的效果。

  2. 模板动态加载: 对于模板文件,可以在运行时从外部文件系统加载,而不是使用 embed。这样,当模板文件更新时,应用程序可以自动加载并使用新的模板。

  3. 插件机制: 对于更复杂的需求,可以考虑使用插件机制(如 Go 插件系统)。通过动态加载插件,可以实现更灵活的功能更新,但这通常涉及到更多的复杂性和安全性考虑。

  4. 定期重建: 对于某些场景,可以设计定期重建二进制文件的流程,将最新的文件嵌入其中。这可以通过自动化脚本和 CI/CD 管道来实现。

需要注意的是,embed 包本身并不支持动态更新,但结合其他技术和方法,可以实现类似的效果。在设计解决方案时,应根据具体需求权衡各种方法的优缺点。

回到顶部