前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >将静态资源嵌入go二进制文件

将静态资源嵌入go二进制文件

作者头像
有点技术
发布2021-01-21 09:53:13
1.3K0
发布2021-01-21 09:53:13
举报
文章被收录于专栏:有点技术有点技术

embed

通过embed 包可以在go应用程序运行时访问嵌入的文件,go1.16功能

在import "embed" 后的Go源文件可以使用// go:embed指令在编译时从包目录或子目录读取文件内容来初始化string、[]byte或FS类型的变量。

例如,以下三种方法可嵌入名为hello.txt的文件,然后在运行时打印其内容:

代码语言:javascript
复制
import "embed"//go:embed hello.txtvar s stringprint(s)//go:embed hello.txtvar b []byteprint(string(b))//go:embed hello.txtvar f embed.FSdata, _ := f.ReadFile("hello.txt")print(string(data))

指令

变量声明上方的// go:embed指令使用一个或多个path.Match模式指定要嵌入的文件。

该指令必须紧接在包含单个变量声明的行之前。在指令和声明之间仅允许空行和'//'行注释。

该变量的类型必须为string,[]byte或FS。不允许使用命名类型或从这些类型派生的类型别名。

例如:

代码语言:javascript
复制
package serverimport "embed"// content holds our static web server content.//go:embed image/* template/*//go:embed html/index.htmlvar content embed.FS

Go构建系统将识别指令,并安排使用文件系统中的匹配文件填充声明的变量(在上面的示例中为content)

// go:embed指令为了简洁起见接受多个以空格分隔的模式,但是也可以重复执行此操作,以避免在有许多模式时出现很长的行。模式是相对于包含源文件的软件包目录来解释的。即使在Windows系统上,路径分隔符也是一个正斜杠。为了命名名称中带有空格的文件,可以将模式写为Go双引号或反引号字符串文字。

如果模式命名目录,则以该目录为根的子树中的所有文件都将被嵌入(递归),但文件名以"."开头的文件除外。或'_'排除在外。因此,上面示例中的变量几乎等同于:

代码语言:javascript
复制
// content is our static web server content.//go:embed image template html/index.htmlvar content embed.FS

区别在于,"image/*"嵌入"image/.tempfile",而"image"没有嵌入。

// go:embed指令可以与导出和未导出的变量一起使用,具体取决于软件包是否希望使数据可用于其他软件包。同样,它可以与全局变量和局部函数一起使用,这取决于上下文中更方便的方法。

模式不得与包模块外部的文件匹配,例如".git/*"或符号链接。空目录的匹配将被忽略。之后,// go:embed行中的每个模式必须至少匹配一个文件或非空目录。

模式不得包含"." 或".."路径元素也不能以斜杠开头。要匹配当前目录中的所有内容,请使用"*"而不是"."。

如果任何模式无效或匹配无效,则构建将失败。

Strings and Bytes

类型为string或[]byte的变量的// go:embed行只能有一个模式,该模式只能与一个文件匹配。Strings或[]byte用该文件的内容初始化。

// go:embed指令即使使用String或[]byte也需要导入"embed"。在不引用embed.FS的源文件中,使用空白导入(import _"embed")。

File Systems

为了嵌入单个文件,通常最好使用string或[]byte类型的变量。FS类型可以嵌入文件树,例如上面的示例中的静态Web服务器内容目录。

FS实现io/fs包的FS接口,因此它可以与任何了解文件系统的包一起使用,包括net/http,text/template和html/template。

例如,给定上面示例中的content变量,我们可以编写:

代码语言:javascript
复制
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(content))))template.ParseFS(content, "*.tmpl")

将静态文件打包入go程序

•创建test项目

代码语言:javascript
复制
mkdir testcd testgo mod init test

•创建静态资源

代码语言:javascript
复制
mkdir staticecho "hello world" > index.html

•测试嵌入资源

1.string模式

代码语言:javascript
复制
package mainimport (    _ "embed"    "net/http")//go:embed static/index.htmlvar static stringfunc main()  {    r := http.NewServeMux()    r.HandleFunc("/", echo)    srv := &http.Server{        Handler:      r,        Addr:         "localhost:8080",    }    srv.ListenAndServe()}func echo(w http.ResponseWriter, r *http.Request)  {    w.Write([]byte(static))}

测试

代码语言:javascript
复制
curl http://localhost:8080/static/

1.fs 模式

代码语言:javascript
复制
package mainimport (    "embed"    "net/http")//go:embed staticvar static embed.FSfunc main()  {    r := http.NewServeMux()    //r.HandleFunc("/", echo)    webapp := http.FileServer(http.FS(static))    r.Handle("/",webapp)    srv := &http.Server{        Handler:      r,        Addr:         "localhost:8080",    }    srv.ListenAndServe()}

测试

代码语言:javascript
复制
curl http://localhost:8080/static/index2.html
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 有点技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • embed
  • 指令
  • Strings and Bytes
  • File Systems
  • 将静态文件打包入go程序
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档