目录结构
E:goprojFileStorageDisk
│ main.go
│ program.txt
│
├─handler
│ handler.go
│
├─meta
│ filemeta.go
│
├─static
│ └─view
│ index.html
│
└─util
util.go
文件元信息接口
文件元信息数据结构:metafilemeta.go
package meta
// FileMeta: 文件元信息结构
type FileMeta struct {
FileSha1 string // unique id
FileName string
FileSize int64
Location string
UploadAt string
}
// 存储每个上传文件的元信息,key是文件的FileSha1
var fileMetas map[string]FileMeta
// 初始化
func init() {
fileMetas = make(map[string]FileMeta)
}
// 接口1:更新或新增文件元信息
func UpdateFileMeta(fmeta FileMeta) {
fileMetas[fmeta.FileSha1] = fmeta
}
// 接口2:通过唯一标识获取文件的元信息对象
func GetFileMeta(fsha1 string) FileMeta {
return fileMetas[fsha1]
}
获取文件元信息的接口
更新handlerhandler.go
func UploadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
...
} else if r.Method == "POST" {
...
defer file.Close()
fileMeta := meta.FileMeta{
FileName: head.Filename,
Location: "/tmp/" + head.Filename,
UploadAt: time.Now().Format("2006-01-02 15:04:05"),
}
// newfile, err := os.Create("/tmp/" + head.Filename)
newfile, err := os.Create(fileMeta.Location)
...
fileMeta.FileSize, err = io.Copy(newfile, file)
if err != nil {
fmt.Printf("Failed to save the data to file, err:%sn", err.Error())
return
}
newfile.Seek(0, 0) // 把文件句柄的位置移到开始位置
fileMeta.FileSha1 = util.FileSha1(newfile) // 计算文件sha1值
meta.UpdateFileMeta(fileMeta) // 更新文件元信息
http.Redirect(w, r, "/file/upload/ok", http.StatusFound)
}
}
// 获取文件元信息的接口
func GetFileMetaHandler(w http.ResponseWriter, r *http.Request) {
// 需要解析客户端发送请求的参数
r.ParseForm()
filehash := r.Form["filehash"][0] // filehash要与前端对应
// 获取文件元信息对象
fMeta := meta.GetFileMeta(filehash)
// 转成jsonString格式返回客户端
data, err := json.Marshal(fMeta)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
w.Write(data)
}
最后,记得到main.go注册handler function
http.HandleFunc("/file/meta", handler.GetFileMetaHandler)
utilutil.go 是一个工具包,提供计算文件元信息的函数。
上传示例
- 任意上传一张图片
- 计算这张图片的sha1值
- 文件上传成功后,访问获取文件元信息的接口
http://localhost:8080/file/meta?filehash=该文件的sha1值