breakpoint_continue.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package utils
  2. import (
  3. "errors"
  4. "os"
  5. "strconv"
  6. "strings"
  7. )
  8. // 前端传来文件片与当前片为什么文件的第几片
  9. // 后端拿到以后比较次分片是否上传 或者是否为不完全片
  10. // 前端发送每片多大
  11. // 前端告知是否为最后一片且是否完成
  12. const (
  13. breakpointDir = "./breakpointDir/"
  14. finishDir = "./fileDir/"
  15. )
  16. //@author: [piexlmax](https://github.com/piexlmax)
  17. //@function: BreakPointContinue
  18. //@description: 断点续传
  19. //@param: content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string
  20. //@return: error, string
  21. func BreakPointContinue(content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string) (string, error) {
  22. path := breakpointDir + fileMd5 + "/"
  23. err := os.MkdirAll(path, os.ModePerm)
  24. if err != nil {
  25. return path, err
  26. }
  27. pathC, err := makeFileContent(content, fileName, path, contentNumber)
  28. return pathC, err
  29. }
  30. //@author: [piexlmax](https://github.com/piexlmax)
  31. //@function: CheckMd5
  32. //@description: 检查Md5
  33. //@param: content []byte, chunkMd5 string
  34. //@return: CanUpload bool
  35. func CheckMd5(content []byte, chunkMd5 string) (CanUpload bool) {
  36. fileMd5 := MD5V(content)
  37. if fileMd5 == chunkMd5 {
  38. return true // 可以继续上传
  39. } else {
  40. return false // 切片不完整,废弃
  41. }
  42. }
  43. //@author: [piexlmax](https://github.com/piexlmax)
  44. //@function: makeFileContent
  45. //@description: 创建切片内容
  46. //@param: content []byte, fileName string, FileDir string, contentNumber int
  47. //@return: string, error
  48. func makeFileContent(content []byte, fileName string, FileDir string, contentNumber int) (string, error) {
  49. if strings.Index(fileName, "..") > -1 || strings.Index(FileDir, "..") > -1 {
  50. return "", errors.New("文件名或路径不合法")
  51. }
  52. path := FileDir + fileName + "_" + strconv.Itoa(contentNumber)
  53. f, err := os.Create(path)
  54. if err != nil {
  55. return path, err
  56. } else {
  57. _, err = f.Write(content)
  58. if err != nil {
  59. return path, err
  60. }
  61. }
  62. defer f.Close()
  63. return path, nil
  64. }
  65. //@author: [piexlmax](https://github.com/piexlmax)
  66. //@function: makeFileContent
  67. //@description: 创建切片文件
  68. //@param: fileName string, FileMd5 string
  69. //@return: error, string
  70. func MakeFile(fileName string, FileMd5 string) (string, error) {
  71. rd, err := os.ReadDir(breakpointDir + FileMd5)
  72. if err != nil {
  73. return finishDir + fileName, err
  74. }
  75. _ = os.MkdirAll(finishDir, os.ModePerm)
  76. fd, err := os.OpenFile(finishDir+fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o644)
  77. if err != nil {
  78. return finishDir + fileName, err
  79. }
  80. defer fd.Close()
  81. for k := range rd {
  82. content, _ := os.ReadFile(breakpointDir + FileMd5 + "/" + fileName + "_" + strconv.Itoa(k))
  83. _, err = fd.Write(content)
  84. if err != nil {
  85. _ = os.Remove(finishDir + fileName)
  86. return finishDir + fileName, err
  87. }
  88. }
  89. return finishDir + fileName, nil
  90. }
  91. //@author: [piexlmax](https://github.com/piexlmax)
  92. //@function: RemoveChunk
  93. //@description: 移除切片
  94. //@param: FileMd5 string
  95. //@return: error
  96. func RemoveChunk(FileMd5 string) error {
  97. err := os.RemoveAll(breakpointDir + FileMd5)
  98. return err
  99. }