前端编写代码,接受文件,后端框架中,直接拿到文件句柄信息,然后写入本地,同时注意跟新文件元信息
// UploadHandler : 处理文件上传
func UploadHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
// 返回上传html页面
data, err := ioutil.ReadFile("./static/view/index.html")
if err != nil {
io.WriteString(w, "internel server error")
return
}
io.WriteString(w, string(data))
} else if r.Method == "POST" {
// 接收文件流及存储到本地目录
file, head, err := r.FormFile("file")
if err != nil {
fmt.Printf("Failed to get data, err:%s\n", err.Error())
return
}
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(fileMeta.Location)
if err != nil {
fmt.Printf("Failed to create file, err:%s\n", err.Error())
return
}
defer newFile.Close()
fileMeta.FileSize, err = io.Copy(newFile, file)
if err != nil {
fmt.Printf("Failed to save data into file, err:%s\n", err.Error())
return
}
newFile.Seek(0, 0)
fileMeta.FileSha1 = util.FileSha1(newFile)
meta.UpdateFileMeta(fileMeta)
http.Redirect(w, r, "/file/upload/suc", http.StatusFound)
}
}
文件上传成功会有一个跳转操作
// UploadSucHandler : 上传已完成
func UploadSucHandler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Upload finished!")
}
文件元信息
// FileMeta : 文件元信息结构
type FileMeta struct {
FileSha1 string
FileName string
FileSize int64
Location string
UploadAt string
}
var fileMetas map[string]FileMeta
func init() {
fileMetas = make(map[string]FileMeta)
}
// UpdateFileMeta : 新增/更新文件元信息
func UpdateFileMeta(fmeta FileMeta) {
fileMetas[fmeta.FileSha1] = fmeta
}
// GetFileMeta : 通过sha1值获取文件的元信息对象
func GetFileMeta(fileSha1 string) FileMeta {
return fileMetas[fileSha1]
}
// GetLastFileMetas : 获取批量的文件元信息列表
func GetLastFileMetas(count int) []FileMeta {
// fMetaArray := make([]FileMeta, len(fileMetas))
// 修复数组元素添加的bug
var fMetaArray []FileMeta
for _, v := range fileMetas {
fMetaArray = append(fMetaArray, v)
}
sort.Sort(ByUploadTime(fMetaArray))
if count > len(fMetaArray) {
return fMetaArray
}
return fMetaArray[0:count]
}
// RemoveFileMeta : 删除元信息
func RemoveFileMeta(fileSha1 string) {
delete(fileMetas, fileSha1)
}
查询批量的文件元信息
// FileQueryHandler : 查询批量的文件元信息
func FileQueryHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
limitCnt, _ := strconv.Atoi(r.Form.Get("limit"))
fileMetas := meta.GetLastFileMetas(limitCnt)
data, err := json.Marshal(fileMetas)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-type", "application/json")
w.Write(data)
}
删除文件
// FileDeleteHandler : 删除文件及元信息
func FileDeleteHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fileSha1 := r.Form.Get("filehash")
fMeta := meta.GetFileMeta(fileSha1)
os.Remove(fMeta.Location)
meta.RemoveFileMeta(fileSha1)
w.WriteHeader(http.StatusOK)
}