Go内嵌静态资源 go-bindata 的安装及使用

我们在开发应用的时候,有时会遇到需要使用静态资源文件的情况。对于Go语言来讲,编码,编译,生成一个单一的可执行文件,感觉特别干净清爽。但是有了静态资源文件,还得一同发布相应的文件,也给程序的部署增添了麻烦。既然发布单独一个可执行文件是非常简单的操作,就有人会想办法把静态资源文件打包进 Go 的程序文件中。以太坊的编码者就用这种方式嵌入了2套 javascript程序 bignumber.js 和 web3.js。

嵌入工具有 go.rice,esc,go generate, go-bindata 等。其中,go-bindata有丰富的 API,还可以压缩存储,是比较好的选择,而且以太坊也是用 go-bindata 来嵌入js文件的。本文就以go-bindata为例来说明静态资源嵌入的办法。

1. 安装Go-bindata

Go-bindata的官网在 这里,官网提供了最新版本的下载,还提供了一些相当简略的说明。
下面是安装命令:

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

安装完了之后可能会找不到go-bindata,提示错误:“-bash: /usr/bin/go-bindata: No such file or directory”。原因在于由于没有定义GOBIN目录,它会自动安装到GOPATH\bin目录下。去那里找找。
找到之后,在PATH里面追加go-bindata的路径。

#通过命令行加入GOBIN的PATH
export PATH=$PATH:$GOPATH/bin
#编辑启动配置文件,开机后自动加载这个路径
nano ~/.bashrc
#编辑完成后,重新加载环境变量到内存
source ~/.bashrc

下面是安装完成后的确认结果。

root@xxx:~/golangwork# go-bindata -version
go-bindata 3.1.0 (Go runtime go1.9.7).
Copyright (c) 2010-2013, Jim Teeuwen.

root@xxx:~/golangwork# go-bindata
Missing <input dir>

Usage: go-bindata [options] <input directories>

  -debug
        Do not embed the assets, but provide the embedding API. Contents will still be loaded from disk.
  -dev
        Similar to debug, but does not emit absolute paths. Expects a rootDir variable to already exist in the generated code's package.
  -ignore value
        Regex pattern to ignore
  -mode uint
        Optional file mode override for all files.
  -modtime int
        Optional modification unix timestamp override for all files.
  -nocompress
        Assets will *not* be GZIP compressed when this flag is specified.
  -nomemcopy
        Use a .rodata hack to get rid of unnecessary memcopies. Refer to the documentation to see what implications this carries.
  -nometadata
        Assets will not preserve size, mode, and modtime info.
  -o string
        Optional name of the output file to be generated. (default "./bindata.go")
  -pkg string
        Package name to use in the generated code. (default "main")
  -prefix string
        Optional path prefix to strip off asset names.
  -tags string
        Optional set of build tags to include.
  -version
        Displays version information.

注意:
不要使用"apt install go-bindata "来安装。会得到一个不好用的版本。
同样是3.1.0版,提示可以使用的参数少5个。

root@xxx:/# go-bindata -version
go-bindata 3.1.0 (Go runtime go1.2.1).
Copyright (c) 2010-2013, Jim Teeuwen.

root@xxx:/# go-bindata
Missing <input dir>

Usage: go-bindata [options] <input directories>

  -debug=false: Do not embed the assets, but provide the embedding API. Contents will still be loaded from disk.
  -nocompress=false: Assets will *not* be GZIP compressed when this flag is specified.
  -nomemcopy=false: Use a .rodata hack to get rid of unnecessary memcopies. Refer to the documentation to see what implications this carries.
  -o="./bindata.go": Optional name of the output file to be generated.
  -pkg="main": Package name to use in the generated code.
  -prefix="": Optional path prefix to strip off asset names.
  -tags="": Optional set of uild tags to include.
  -version=false: Displays version information.

2. 使用Go-bindata生成嵌入go代码

下面是将当前目录下的bignumber.js以及web3.js代码以压缩二进制代码嵌入到go语言中,生成bindata.go源程序。

go-bindata -nometadata -pkg deps -o bindata.go bignumber.js web3.js

下面是生成代码的一部分,“DO NOT EDIT!” 排版也很漂亮。
在这里插入图片描述
下面是Javascript转成二进制数据后的样子。这里也可以看到二进制数据在go语言里面的存储方式。
在这里插入图片描述

RLP 是英文 Recursive Length Prefix 的缩写,即递归长度前缀编码,RLP主要用于以太坊数据的网络传输和持久化存储。 以下数据中,十六进制表示数字前面会加‘0x’, 十进制 ...