Searching...

[TOC]

gres资源管理

GF框架从v1.9版本开始提供了资源管理的特性,由gres模块实现,该模块具有以下特点: - 可将任意的文件打包为Go内容,支持开发者自定义加解密; - 资源管理器内容完全基于内存,并且内容只读,无法动态修改; - 资源管理器默认整合支持到了WebServer、配置管理、模板引擎中; - 任意文件如网站静态文件、配置文件等可编译到二进制文件中,也可编译到发布的可执行文件中; - 开发者可只需编译发布一个可执行文件,除了方便了软件分发,也为保护软件知识产权内容提供了可能;

使用方式

import "github.com/gogf/gf/os/gres"

接口文档

https://godoc.org/github.com/gogf/gf/os/gres

func Add(content []byte, prefix ...string) error
func Contains(path string) bool
func Dump()
func GetContent(path string) []byte
func IsEmpty() bool
func Get(path string) *File
func GetWithIndex(path string, indexFiles []string) *File
func ScanDir(path string, pattern string, recursive ...bool) []*File
func ScanDirFile(path string, pattern string, recursive ...bool) []*File
func Load(path string, prefix ...string) error

func Pack(srcPaths string, keyPrefix ...string) ([]byte, error)
func PackToGoFile(srcPath, goFilePath, pkgName string, keyPrefix ...string) error
func PackToFile(srcPaths, dstPath string, keyPrefix ...string) error
func Unpack(path string) ([]*File, error)
func UnpackContent(content []byte) ([]*File, error)
type File
    func (f *File) Close() error
    func (f *File) Content() []byte
    func (f *File) FileInfo() os.FileInfo
    func (f *File) Name() string
    func (f *File) Open() (io.ReadCloser, error)
    func (f *File) Read(b []byte) (n int, err error)
    func (f *File) Readdir(count int) ([]os.FileInfo, error)
    func (f *File) Seek(offset int64, whence int) (int64, error)
    func (f *File) Stat() (os.FileInfo, error)
type Resource
    func Instance(name ...string) *Resource
    func New() *Resource
    func (r *Resource) Add(content []byte, prefix ...string) error
    func (r *Resource) Contains(path string) bool
    func (r *Resource) Dump()
    func (r *Resource) Get(path string) *File
    func (r *Resource) GetContent(path string) []byte
    func (r *Resource) GetWithIndex(path string, indexFiles []string) *File
    func (r *Resource) IsEmpty() bool
    func (r *Resource) Load(path string, prefix ...string) error
    func (r *Resource) ScanDir(path string, pattern string, recursive ...bool) []*File
    func (r *Resource) ScanDirFile(path string, pattern string, recursive ...bool) []*File
  1. 通过Pack*/Unpack*方法可以实现对任意文件的打包/解包功能,可以打包到二进制文件或者Go代码文件;
  2. 资源管理由Resource对象实现,可实现对打包内容的添加,文件的检索查找,以及对目录的遍历等功能;
  3. 资源文件由File对象实现,该文件对象和os.File文件对象类似,并且该对象实现了http.File接口;
  4. ScanDir用于针对于特定目录下的文件/目录检索,并且支持递归检索;
  5. ScanDirFile用于针对于特定目录下的文件检索,并且支持递归检索;
  6. 通过Dump方法在终端打印出Resource资源对象所有的文件列表,资源管理器中的文件分隔符号统一为/
  7. 此外,gres资源管理模块提供了默认的Resource对象,并通过包方法提供了对该默认对象的操作;

文件/目录打包

开发者对文件/目录的打包可以自定义通过Pack*方法实现,并通过Unpack*方法自行对二进制文件进行打包;或者通过import方式导入打包的Go资源文件。

开发者也可以通过gf命令行工具的pack命令实现对任意文件的打包,具体请查看CLI工具链章节。通过命令行工具的pack命令也是比较推荐的打包方式。

可以通过Pack方法直接生成打包后的[]byte内容,开发者可以对该内容进行自定义加密以额外增加文件内容的安全性。随后可以在程序中对该[]byte解密后,并通过UnpackContent方法可以对该内容进行解包,使用该打包内容。

打包生成Go文件

这种是比较常用的方式,我们这里直接使用gf工具来进行打包,不添加自定义的加密。

1. gf pack生成Go文件

比较推荐的方式是将Go文件直接生成到boot启动目录,并设置生成Go文件的包名为boot,这样该资源文件将会被自动引入到项目中。我们将项目的config,public,template三个目录的文件打包到Go文件,打包命令为:gf pack config,public,template boot/data.go -n boot

生成的Go文件内容类似于:

import "github.com/gogf/gf/os/gres"

func init() {
	if err := gres.Add([]byte("\x50\x4b\x03\x04\x14\x00\x08...")); err != nil {
		panic(err)
	}
}

2. 使用打包的Go资源文件

由于项目的main入口程序文件会引入boot包,例如像这样(module名称为my-app):

import (
	_ "my-app/boot"
)

随后可以在项目的任何地方使用gres模块来访问打包的资源文件。

如果使用GF推荐的项目目录结构,在目录结构中会存在boot目录(对应包名也是boot),用于程序启动设置。因此如果将Go资源文件打包到boot目录下,那么将会被自动编译进可执行文件中。

3. 打印资源管理文件列表

可以通过Dump()方法打印出当前资源管理器中所有的文件列表,输出内容类似于:

2019-09-15T13:36:28+00:00   0.00B config
2019-07-27T07:26:12+00:00   1.34K config/config.toml
2019-09-15T13:36:28+00:00   0.00B public
2019-06-25T17:03:56+00:00   0.00B public/resource
2018-12-04T12:50:16+00:00   0.00B public/resource/css
2018-12-17T12:54:26+00:00   0.00B public/resource/css/document
2018-12-17T12:54:26+00:00   4.20K public/resource/css/document/style.css
2018-08-24T01:46:58+00:00  32.00B public/resource/css/index.css
2019-05-23T03:51:24+00:00   0.00B public/resource/image
2018-08-20T05:02:08+00:00  24.01K public/resource/image/cover.png
2019-05-23T03:51:24+00:00   4.19K public/resource/image/favicon.ico
2018-08-23T01:44:50+00:00   4.19K public/resource/image/gf.ico
2018-12-04T13:04:34+00:00   0.00B public/resource/js
2019-06-27T11:06:12+00:00   0.00B public/resource/js/document
2019-06-27T11:06:12+00:00  11.67K public/resource/js/document/index.js
2019-09-15T13:36:28+00:00   0.00B template
2019-02-02T09:08:56+00:00   0.00B template/document
2018-12-04T12:49:08+00:00   0.00B template/document/include
2018-12-04T12:49:08+00:00 329.00B template/document/include/404.html
2019-03-06T01:52:56+00:00   3.42K template/document/index.html
...

自定义打包/解包

自定义打包示例

我们将项目根目录下的publicconfig目录打包为data.bin二进制文件,并通过gaes加密算法对生成的二进制内容进行加密。

package main

import (
	"github.com/gogf/gf/crypto/gaes"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/gres"
)

var (
	CryptoKey = []byte("x76cgqt36i9c863bzmotuf8626dxiwu0")
)

func main() {
	binContent, err := gres.Pack("public,config")
	if err != nil {
		panic(err)
	}
	binContent, err = gaes.Encrypt(binContent, CryptoKey)
	if err != nil {
		panic(err)
	}
	if err := gfile.PutBytes("data.bin", binContent); err != nil {
		panic(err)
	}
}

自定义解包示例

我们使用将刚才打包生成的data.bin,需要解密和解包两步操作。

package main

import (
	"github.com/gogf/gf/crypto/gaes"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/gres"
)

var (
	CryptoKey = []byte("x76cgqt36i9c863bzmotuf8626dxiwu0")
)

func main() {
	binContent := gfile.GetBytes("data.bin")
	binContent, err := gaes.Decrypt(binContent, CryptoKey)
	if err != nil {
		panic(err)
	}
	if err := gres.Add(binContent); err != nil {
		panic(err)
	}
	gres.Dump()
}

最后,我们使用gres.Dump()打印出添加成功的文件列表。