断点续传 开发中
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gin-vue-admin/controller/servers"
|
||||
"gin-vue-admin/model/dbModel"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 断点续传到服务器
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "断点续传示例"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"上传成功"}"
|
||||
// @Router /fileUploadAndDownload/breakpointContinue [post]
|
||||
|
||||
func BreakpointContinue(c *gin.Context) {
|
||||
fileMd5 := c.Request.FormValue("fileMd5")
|
||||
fileName := c.Request.FormValue("fileName")
|
||||
chunkMd5 := c.Request.FormValue("chunkMd5")
|
||||
chunkNumber, _ := strconv.Atoi(c.Request.FormValue("chunkNumber"))
|
||||
chunkTotal, _ := strconv.Atoi(c.Request.FormValue("chunkTotal"))
|
||||
_, FileHeader, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
servers.ReportFormat(c, false, fmt.Sprintf("%v", err), gin.H{})
|
||||
} else {
|
||||
f, err := FileHeader.Open()
|
||||
if err != nil {
|
||||
servers.ReportFormat(c, false, fmt.Sprintf("%v", err), gin.H{})
|
||||
} else {
|
||||
cen, _ := ioutil.ReadAll(f)
|
||||
defer f.Close()
|
||||
if flag := servers.CheckMd5(cen, chunkMd5); flag {
|
||||
err, file := new(dbModel.ExaFile).FindOrCreateFile(fileMd5, fileName, chunkTotal)
|
||||
if err != nil {
|
||||
servers.ReportFormat(c, false, fmt.Sprintf("%v", err), gin.H{})
|
||||
} else {
|
||||
err, pathc := servers.BreakPointContinue(cen, fileName, chunkNumber, chunkTotal, fileMd5)
|
||||
if err != nil {
|
||||
servers.ReportFormat(c, false, fmt.Sprintf("%v", err), gin.H{})
|
||||
} else {
|
||||
err = file.CreateFileChunk(pathc, chunkNumber)
|
||||
if err != nil {
|
||||
servers.ReportFormat(c, false, fmt.Sprintf("%v", err), gin.H{})
|
||||
} else {
|
||||
servers.ReportFormat(c, true, "切片创建成功", gin.H{})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 查找文件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file params file true "查找文件"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查找成功"}"
|
||||
// @Router /fileUploadAndDownload/findFile [post]
|
||||
func FindFile(c *gin.Context) {
|
||||
fileMd5 := c.Query("fileMd5")
|
||||
fileName := c.Query("fileName")
|
||||
chunkTotal, _ := strconv.Atoi(c.Query("chunkTotal"))
|
||||
err, file := new(dbModel.ExaFile).FindOrCreateFile(fileMd5, fileName, chunkTotal)
|
||||
if err != nil {
|
||||
servers.ReportFormat(c, false, fmt.Sprintf("查找失败:%v", err), gin.H{})
|
||||
} else {
|
||||
servers.ReportFormat(c, true, "查找成功", gin.H{"file": file})
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 查找文件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file params file true "查找文件"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查找成功"}"
|
||||
// @Router /fileUploadAndDownload/findFile [post]
|
||||
func BreakpointContinueFinish(c *gin.Context) {
|
||||
fileMd5 := c.Query("fileMd5")
|
||||
fileName := c.Query("fileName")
|
||||
err, filePath := servers.MakeFile(fileName, fileMd5)
|
||||
if err != nil {
|
||||
servers.ReportFormat(c, true, fmt.Sprintf("文件创建失败:%v", err), gin.H{})
|
||||
} else {
|
||||
servers.ReportFormat(c, true, "文件创建成功", gin.H{"filePath": filePath})
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 删除切片
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file params file true "查找文件"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查找成功"}"
|
||||
// @Router /fileUploadAndDownload/removeChunk [post]
|
||||
func RemoveChunk(c *gin.Context) {
|
||||
fileMd5 := c.Query("fileMd5")
|
||||
fileName := c.Query("fileName")
|
||||
filePath := c.Query("filePath")
|
||||
err := servers.RemoveChunk(fileMd5)
|
||||
err = new(dbModel.ExaFile).DeleteFileChunk(fileMd5, fileName, filePath)
|
||||
if err != nil {
|
||||
servers.ReportFormat(c, true, fmt.Sprintf("缓存切片删除失败:%v", err), gin.H{})
|
||||
} else {
|
||||
servers.ReportFormat(c, true, "缓存切片删除成功", gin.H{})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"gin-vue-admin/tools"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// 前端传来文件片与当前片为什么文件的第几片
|
||||
// 后端拿到以后比较次分片是否上传 或者是否为不完全片
|
||||
// 前端发送每片多大
|
||||
// 前端告知是否为最后一片且是否完成
|
||||
|
||||
const breakpointDir = "./breakpointDir/"
|
||||
const finishDir = "./fileDir/"
|
||||
|
||||
func BreakPointContinue(content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string) (error, string) {
|
||||
path := breakpointDir + fileMd5 + "/"
|
||||
err := os.MkdirAll(path, os.ModePerm)
|
||||
if err != nil {
|
||||
return err, path
|
||||
}
|
||||
err, pathc := makeFileContent(content, fileName, path, contentNumber)
|
||||
return err, pathc
|
||||
|
||||
}
|
||||
|
||||
func CheckMd5(content []byte, chunkMd5 string) (CanUpload bool) {
|
||||
fileMd5 := tools.MD5V(content)
|
||||
if fileMd5 == chunkMd5 {
|
||||
return true // "可以继续上传"
|
||||
} else {
|
||||
return false // "切片不完整,废弃"
|
||||
}
|
||||
}
|
||||
|
||||
func makeFileContent(content []byte, fileName string, FileDir string, contentNumber int) (error, string) {
|
||||
path := FileDir + fileName + "_" + strconv.Itoa(contentNumber)
|
||||
f, err := os.Create(path)
|
||||
defer f.Close()
|
||||
if err != nil {
|
||||
return err, path
|
||||
} else {
|
||||
_, err = f.Write(content)
|
||||
if err != nil {
|
||||
return err, path
|
||||
}
|
||||
}
|
||||
return nil, path
|
||||
}
|
||||
|
||||
func MakeFile(fileName string, FileMd5 string) (error, string) {
|
||||
rd, err := ioutil.ReadDir(breakpointDir + FileMd5)
|
||||
if err != nil {
|
||||
return err, finishDir + fileName
|
||||
}
|
||||
_ = os.MkdirAll(finishDir, os.ModePerm)
|
||||
fd, _ := os.OpenFile(finishDir+fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
|
||||
for k, _ := range rd {
|
||||
content, _ := ioutil.ReadFile(breakpointDir + FileMd5 + "/" + fileName + "_" + strconv.Itoa(k))
|
||||
_, err = fd.Write(content)
|
||||
if err != nil {
|
||||
_ = os.Remove(finishDir + fileName)
|
||||
return err, finishDir + fileName
|
||||
}
|
||||
}
|
||||
defer fd.Close()
|
||||
return nil, finishDir + fileName
|
||||
}
|
||||
|
||||
func RemoveChunk(FileMd5 string) error {
|
||||
err := os.RemoveAll(breakpointDir + FileMd5)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user