静态资源打包rice
静态资源打包rice
go在打包的时候,源代码能打包,其他用的的资源文件,如果不特殊处理,是不会打包的文件里面的。所以,有这样的一种需求,打包生成的文件,最好只有一个exe执行文件,这样,方便使用。用过filebrowser工具,构建好的文件,只是一个文件,看过它的源码,需要安装rice工具。所以呢,本文,简单的记录rice的使用。
参考资源
使用步骤
安装工具
理论上下面第2个命令执行就能安装工具,但是,我也执行了前一个命令。
go get github.com/GeertJohan/go.rice
go get github.com/GeertJohan/go.rice/...
代码
改造好后的代码,如下,一是引入库,二是添加下面这句。
rice.MustFindBox("public").HTTPBox()))
改造后:
package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"path"
"path/filepath"
"github.com/GeertJohan/go.rice"
)
var port = flag.String("port", "8082", "web监听的端口")
var rootdir = flag.String("root", ".", "web服务器的根目录")
func main() {
flag.Parse()
handleString("/", index)
handleString("/frame.js", framejs)
http.HandleFunc("/getdir/", getdir)
http.HandleFunc("/search/", search)
http.HandleFunc("/download/", downloadFile)
//http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("public/"))))
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(rice.MustFindBox("public").HTTPBox())))
fmt.Println("web服务监听的端口: " + *port)
fmt.Println("请浏览器输入以下地址访问")
fmt.Println("http://localhost:" + *port)
log.Fatal(http.ListenAndServe(":"+*port, nil))
}
func handleString(pattern, content string) {
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, content)
})
}
type dirinfo struct {
Id string `json:"id"`
Text string `json:"text"`
AbsPath string `json:"absPath"`
Leaf bool `json:"leaf"`
}
type dirinfolist []*dirinfo
//获取目录
func getdir(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
var dlist dirinfolist
path := r.PostForm.Get("node")
if path == "src" || path == "" {
path = *rootdir
}
// fmt.Println("path:", path)
fileInfoList, err := ioutil.ReadDir(path)
if err != nil {
log.Fatal(err)
}
// fmt.Println(len(fileInfoList))
for i := range fileInfoList {
if !fileInfoList[i].IsDir() {
continue
}
curdir := fileInfoList[i].Name()
absPath := path + "/" + curdir
// fmt.Println(curdir) //打印当前文件或目录下的文件或目录名
dinfo := &dirinfo{absPath, curdir, absPath, false}
dlist = append(dlist, dinfo)
}
jsonbyte, _ := json.Marshal(dlist)
// fmt.Print(string(jsonstr))
fmt.Fprint(w, string(jsonbyte))
}
type fileinfo struct {
Abspath string `json:"abspath"`
Path string `json:"path"`
Name string `json:"name"`
Mtime string `json:"mtime"`
Size int64 `json:"size"`
}
type fnlist []*fileinfo
//查找对应的文件
func search(w http.ResponseWriter, r *http.Request) {
var result fnlist
r.ParseForm()
path := r.PostForm.Get("path")
// date := r.PostForm.Get("date")
// fmt.Println(date)
// fmt.Println(path)
if len(path) == 0 {
path = *rootdir
}
filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
count := 0
if !info.IsDir() {
count += 1
result = append(result, &fileinfo{path, path, info.Name(), info.ModTime().String(), info.Size()})
if count > 5000 {
return nil
}
}
return nil
})
if len(result) > 0 {
jsonbyte, _ := json.Marshal(result)
fmt.Fprint(w, string(jsonbyte))
} else {
fmt.Fprint(w, "[]")
}
}
//下载文件
func downloadFile(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fileFullPath := r.Form.Get("path")
file, err := os.Open(fileFullPath)
if err != nil {
fmt.Fprint(w, "文件不存在。")
return
}
defer file.Close()
fileName := path.Base(fileFullPath)
fmt.Println("文件名:", fileName)
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("content-disposition", "attachment; filename=\""+fileName+"\"")
_, error := io.Copy(w, file)
if error != nil {
fmt.Println("error:", err.Error())
return
}
}
在main.go文件下,执行编译资源命令
# rice -h 查看帮助
# 打包资源文件,会生成一个rice-box.go文件。
rice embed-go
总结
在开发期,可以不编译资源,也能使用,这样就方便开发调试,随时更改资源文件。另外,是否运行期,也能生效呢?不得而知。