趁着五一放假,趁着有时间,把欠的一些技术集中研究研究,写写文章,好给自己一个交待。
本文介绍如何在 Golang 中整合静态资源文件,将静态资源文件编译到二进制可执行文件中,这与其它程序的打包可能是一个概念,也可能不是,后续有空研究再补充。

起因

大概10年前,即2011年,也研究一下这方面的内容,主要针对 C 语言,使用 ARM 板子测试。 那篇文章如下图:

当时对技术的兴趣比较浓厚,没想过房子车子的事,现在经常想房子车子,但也被迫对技术感兴趣。因此,使用 Golang 语言重新研究一下。

实践

经查,有2个类似的工具:go-bindata 和 go-bindata-assetfs。两者可以将文件转换成 golang 语言代码,后者似乎依赖于前者,本着使用的目的,暂未研究细节,看了一下生成的 golang 代码,有对外提供的接口,有文件映射表,有真正存储文件的字节流。

安装

使用go get命令安装:

go get -u github.com/go-bindata/go-bindata/...
go get -u github.com/elazarl/go-bindata-assetfs/...

输入对应的命令验证:

go-bindata
go-bindata-assetfs

生成

为适合项目目录,本文约定使用 static 目录存放静态资源文件——即需要打包到可执行程序中的文件,生成的代码,存放到 bindata 目录,且其包名亦为 bindata。经研究发现似乎 go-bindata-assetfs 更好一些,因此本文使用该工具,生成命令如下:

go-bindata-assetfs -o=bindata/bindata.go -pkg=bindata -ignore="README.md" -prefix=static static/...

-o指定了输出文件,-pkg指定包名(一般与前者保持一致),-ignore指定需忽略的文件,-prefix指定文件路径前缀(本例中,指定了前缀,不需在代码中使用static前缀)。如果不需要如此复杂,可将其生成的文件与包 main 在同一目录,包名亦为 main,可用于简单测试:

go-bindata-assetfs -o=bindata.go -ignore="README.md" -prefix=static static/...

为了调试方便——即不需要每次更新文件都要重新编译代码,则可以添加-debug参数,命令如下:

go-bindata-assetfs -debug -o=bindata.go -ignore="README.md" -prefix=static static/...

该参数是在代码中指定静态资源文件绝对路径,因此,修改原文件无需重新编译即可生效,有兴趣可研读生成的代码。

测试

资源文件目录 static 如下:

$ tree static/
static/
|-- conf
|   `-- config.toml
|-- html
|   `-- foo.html
`-- libfoo.so2 directories, 3 files

主要使用的接口如下:

// 获取所有的文件名称
filenames := bindata.AssetNames()// 读取某一文件的内容
filename = "html/foo.html"
content, err = bindata.Asset(filename)

指定的文件,以static为根目录,其形式与一般的路径无差异。

完整测试代码如下:

package mainimport ("fmt""strings""io/ioutil""bindata_test2/bindata"
)func main() {fmt.Println("bindata test..");// 遍历所有文件,打印文件名,并输出html的内容filenames := bindata.AssetNames()for _, item := range  filenames {fmt.Println("got file: ", item)if !strings.HasSuffix(item, ".tmpl") && !strings.HasSuffix(item, ".html") {continue}content, err := bindata.Asset(item)if err != nil {fmt.Printf("not found file %s: %s\n", item, err.Error())}fmt.Println(string(content))fmt.Println("-----------------------------------\n")}// 单独测试filename := "assets/foo.html"content, err := bindata.Asset(filename)if err != nil {fmt.Printf("not found file %s: %s\n", filename, err.Error())}filename = "foo.html"content, err = bindata.Asset(filename)if err != nil {fmt.Printf("not found file %s: %s\n", filename, err.Error())}filename = "html/foo.html"content, err = bindata.Asset(filename)if err != nil {fmt.Printf("not found file %s: %s\n", filename, err.Error())}// content 为二进制buf,怎么用?filename = "conf/config.toml"content, err = bindata.Asset(filename)if err != nil {fmt.Printf("not found file %s: %s\n", filename, err.Error())}fmt.Println(string(content))// 读取so并保存filename = "libfoo.so"content, err = bindata.Asset(filename)if err != nil {fmt.Printf("not found file %s: %s\n", filename, err.Error())return}//filename = "libfoo.so"err = ioutil.WriteFile(filename, content, 0755)if err != nil {fmt.Println("write file error: ", err)return}fmt.Printf("write file %s ok\n", filename)}

以 libfoo.so 文件为例,原文件和保存的文件对比如下:

$ md5sum.exe static/libfoo.so libfoo.so
9416ab261b2867d9acbb563690116885 *static/libfoo.so
9416ab261b2867d9acbb563690116885 *libfoo.so

两者内容是相同的。

扩展

本文所述方法,有一定范围内可以使用,对于大型项目或多人协作项目,不建议使用。
针对该方法,笔者认为可以进行的事有:
1、将 web 服务有关的 css、js、html 等整合到可执行二进制文件中,方便部署。在笔者即将实现的 web 服务中,由于功能唯一,又是内部使用,且还只是由笔者个人实现,因此对技术栈拥有完全自主的决定权,通俗地讲,同事和上头不管技术细节,能实现功能即可,为了方便自己,故如此设计。
2、动态库整合,如果涉及动态库文件的使用,则可以将动态库打包到可执行文件,在运行时读取并保存到指定目录,再加载。此法将二者绑定一起,无法做到只更新动态库文件,因此需慎重。
3、配置文件整合,对于需配置文件的程序而言,在部署时需自带配置文件,或默认首次运行时生成。对于后者,有的直接在代码中固定配置,根据情况写到指定目录,使用本文,则直接将配置文件打包到二进制文件,如不存在,则再写到指定目录。
4、其它待探索发现并实施。

李迟 2021.5.5

Golang实践录:静态资源文件整合:初步使用相关推荐

  1. Golang实践录:静态资源文件整合:web服务

    趁着五一放假,趁着有时间,把欠的一些技术集中研究研究,写写文章,好给自己一个交待. 本文研究静态资源文件的在 web 服务器的整合. 基础 Golang 中的 web 服务框架有很多种,本文选取 gi ...

  2. golang打包HTML为Android,使用Go开发Web服务,并打包html/js/css等静态资源文件

    Go的高性能,使它天生适合开发io方面的服务,Web服务当然不再话下.同时,Go编译后生成的单文件不是字节码,而是对应平台的机器码,因此它效率更高.资源占用更低. 为了更好的进程程序管理,移动程序时更 ...

  3. 解决Spring MVC整合Shiro出现无法访问静态资源文件的问题

    解决方案:shiro过滤器配置拦截器链中添加"/static/**=anno"即可,"/static/**"为静态资源文件路径. <property na ...

  4. golang将静态资源文件打包进二进制文件

    默认情况下,将项目打包成二进制的时候是不会加入静态资源文件的,因此在部署的时候还需要捎带上这些文件,比如,一些配置文件,图片,样式表等. 很多时候,这些静态文件是不需要变的,如果能一并加入到二进制文件 ...

  5. python3读取网页_python3+selenium获取页面加载的所有静态资源文件链接操作

    软件版本: python 3.7.2 selenium 3.141.0 pycharm 2018.3.5 具体实现流程如下,废话不多说,直接上代码: from selenium import webd ...

  6. vue-cli项目布署问题解决:空白页、静态资源文件404错误、refrenceError:promise未定义(部分浏览器不支持ES6语法)

    (前言:文章记录vue-cli项目打包使用IIS布署遇到的几个错误及解决方式) 首先简单理解webpack打包: 个人理解:项目开发中我们构建 "低耦合高内聚" 的组件/模块来代码 ...

  7. Golang实践录:命令行cobra库实例再三优化

    本文是上一文章<Golang实践录:命令行cobra库实例优化> 的优化,主要的子命令的业务实现的整理. 起因 上一版本实现的方式,还是有点不满意,格式也不对齐,重要的是,似乎不是正规的方 ...

  8. Golang实践录:命令行cobra库实例优化

    本文上一文章<Golang实践录:命令行cobra库实例> 的优化,主要的子命令的业务实现的整理. 起因 旧版本中,每个子命令的入口函数,均需一一判断传入参数,并调用对应的业务实现函数,编 ...

  9. 在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案

    在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案 参考文章: (1)在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案 (2)https: ...

最新文章

  1. Oracle11gR2 64bit+Oracle11gR2Client32bit+pl/sql 9
  2. 揭秘Java网络爬虫程序原理
  3. 卷积神经网络Convolutional Neural Network (CNN)
  4. CentOS6.3中挂载NTFS移动硬盘的经历
  5. JVM内存管理(一)--GC简介
  6. 工程师软技能6:理财人生精神
  7. 智能仓储管理系统分析?
  8. XJOI 3281 A * B Problem again 题解
  9. ORACLE SQL优化大全
  10. Win11写字板怎么打开?Win11开启写字板的方法
  11. Typora+图床详解(小白都能学得会)
  12. 智能清晰锐化磨皮图片处理软件Perfectly Clear 3.8.0.1665 汉化版
  13. 图灵机器人 mysql_如何在微信小程序中制作图灵机器人?
  14. 算法导论第十五章:动态规划(一)
  15. 嵌入式系统的体系结构 图解
  16. 数学-上确界与下确界概念
  17. 【Android TV】Android 8.0下 ,TV系统通知音失效
  18. 酒店取消预订预测分析报告
  19. SettingsProvider单编生效
  20. Python正则去除中英文标点的操作手法

热门文章

  1. 富士通成功开发全球最快的36量子位量子模拟器
  2. 大众正式发布ID. Buzz 造型致敬经典
  3. 英伟达吞并ARM的交易计划失败!
  4. 彻底凉凉!两头部网红女主播账号被封,逃税被罚近亿元 还被曝不给员工交社保...
  5. DaDa英语宣布12月31日起全面停止所有外教服务
  6. 拼多多11.11:无定金、不预售,“好牌子、好实惠”底价直降
  7. 苹果 AirPods 固件更新,这个新功能上线!
  8. 霍兰德教育CEO被曝卷钱逃回英国 欠款超千万
  9. OPPO Reno6系列将推Bobbi Brown联名版
  10. 尊贵的iPhone 11用户们,苹果喊你们换显示屏模块了……