Handler.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package server
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "file-manger-server/config"
  6. "file-manger-server/db"
  7. "file-manger-server/domain"
  8. "fmt"
  9. "io"
  10. "os"
  11. "strings"
  12. )
  13. type ReturnCommand interface {
  14. Return() []byte
  15. }
  16. func HandlerReceiveFile(info *ConnInfo, msg []byte) {
  17. var commandId = msg[0]
  18. //事务id解析
  19. var transactionId = msg[1:17]
  20. fmt.Println(ToHexBytes(transactionId))
  21. var tranId = ToHexBytes(transactionId)
  22. if commandId == 0 {
  23. InfoTransaction(info, msg, tranId, 16)
  24. } else if commandId == 1 {
  25. err := InfoTransactionSplit(info, msg, tranId, 16)
  26. fmt.Println(err)
  27. }
  28. }
  29. // InfoTransaction 获取的事务数据内容
  30. func InfoTransaction(info *ConnInfo, msg []byte, transactionId string, transactionIdLen int) error {
  31. // 获取数据,判断事务是否注册
  32. fileUser, err := db.FileUserDao{}.Get(transactionId)
  33. if err != nil {
  34. return errors.New("FileUser transactionId is not found")
  35. }
  36. // 判断用户是否存在
  37. if fileUser.UserId == 0 {
  38. return errors.New("FileUser userId is not found")
  39. }
  40. var index = transactionIdLen + 1
  41. // 文件名称长度
  42. var fileNameLength = binary.BigEndian.Uint32(msg[index : index+4])
  43. index += 4
  44. // 文件名
  45. var filename = string(msg[index : uint32(index)+fileNameLength])
  46. index += int(fileNameLength)
  47. // 文件大小
  48. var fileSize = int64(binary.BigEndian.Uint64(msg[index : index+8]))
  49. index += 8
  50. // 路径长度
  51. var pathLength = binary.BigEndian.Uint32(msg[index : index+4])
  52. index += 4
  53. // 路径
  54. var path = string(msg[index : index+int(pathLength)])
  55. index += int(pathLength)
  56. // 添加专属路径 前缀
  57. path = fmt.Sprint(config.Conf.File.Upload.Path, "/", fileUser.UserId, "/", transactionId, "/", path)
  58. // 分片数量,文件被拆分了几份
  59. var splitCount = binary.BigEndian.Uint32(msg[index : index+4])
  60. index += 4
  61. // 创建时间,修改时间,访问时间
  62. var createTime = binary.BigEndian.Uint64(msg[index : index+8])
  63. index += 8
  64. var modifyTime = binary.BigEndian.Uint64(msg[index : index+8])
  65. index += 8
  66. var accessTime = binary.BigEndian.Uint64(msg[index : index+8])
  67. index += 8
  68. Type := ""
  69. if fileSize == -1 {
  70. Type = "folder"
  71. } else {
  72. Type = "file"
  73. }
  74. //文件扩展名
  75. ExtensionName := ""
  76. suffixIndex := strings.Index(filename, ".")
  77. if suffixIndex != -1 {
  78. ExtensionName = filename[suffixIndex+1:]
  79. }
  80. //填充数据
  81. file := domain.File{
  82. Name: filename,
  83. Url: path,
  84. Size: fileSize,
  85. Type: Type,
  86. MD5: "",
  87. TransactionId: transactionId,
  88. Extension: ExtensionName,
  89. Access: domain.FileAccess{},
  90. CreateUser: 0,
  91. CreateTime: int64(createTime),
  92. UpdateTime: int64(modifyTime),
  93. }
  94. //添加元素
  95. db.FileDao{}.Insert(file)
  96. //递归创建前面的文件夹
  97. lastIndex := strings.LastIndex(path, "/")
  98. if lastIndex != -1 {
  99. err := os.MkdirAll(path[:lastIndex], 0755)
  100. if err != nil {
  101. return err
  102. }
  103. }
  104. if splitCount == 0 {
  105. if fileSize >= 0 {
  106. //打开文件
  107. openFile, err := os.Create(path)
  108. if err != nil {
  109. fmt.Println("err:", err)
  110. }
  111. defer openFile.Close()
  112. var content = msg[77+fileNameLength+pathLength:]
  113. openFile.Write(content)
  114. } else {
  115. err := os.Mkdir(path, 0755)
  116. if err != nil {
  117. fmt.Println(err)
  118. }
  119. }
  120. } else {
  121. // 创建一个空文件
  122. file, err := os.Create(path)
  123. if err != nil {
  124. fmt.Println("Error creating file:", err)
  125. return err
  126. }
  127. defer file.Close() // 确保在函数结束时关闭文件
  128. fmt.Println("file size :", fileSize)
  129. err = file.Truncate(fileSize)
  130. if err != nil {
  131. fmt.Println("Error setting file size:", err)
  132. return err
  133. }
  134. }
  135. // 返回状态信息
  136. //info.conn.Write()
  137. fmt.Println(fmt.Sprintf("事务id:%d\n文件名:%s\n文件大小:%d\n相对路径:%s\n分片数量:%d\n创建时间:%d\n修改时间:%d\n访问时间:%d", transactionId, filename, fileSize, path, splitCount, createTime, modifyTime, accessTime))
  138. return nil
  139. }
  140. // InfoTransactionSplit 获取的事务数据内容
  141. func InfoTransactionSplit(info *ConnInfo, msg []byte, transactionId string, transactionIdLen int) error {
  142. fileUser, err := db.FileUserDao{}.Get(transactionId)
  143. if err != nil {
  144. return errors.New("FileUser transactionId is not found")
  145. }
  146. if fileUser.UserId == 0 {
  147. return errors.New("FileUser userId is not found")
  148. }
  149. var index = transactionIdLen + 1
  150. var splitNum = binary.BigEndian.Uint32(msg[index : index+4])
  151. index += 4
  152. var pathLength = binary.BigEndian.Uint32(msg[index : index+4])
  153. index += 4
  154. var path = string(msg[index : index+int(pathLength)])
  155. index += int(pathLength)
  156. path = fmt.Sprint(config.Conf.File.Upload.Path, "/", fileUser.UserId, "/", transactionId, "/", path)
  157. var content = msg[index:]
  158. err = insertDataAtPosition(path, int64(splitNum*1024), content)
  159. return err
  160. // 返回状态信息
  161. //info.conn.Write()
  162. //fmt.Println(fmt.Sprintf("事务id:%d\n文件名:%s\n文件大小:%d\n相对路径:%s\n分片数量:%d\n创建时间:%d\n修改时间:%d\n访问时间:%d", transactionId, filename, fileSize, path, splitCount, createTime, modifyTime, accessTime))
  163. }
  164. var sign = 0
  165. func insertDataAtPosition(filePath string, position int64, data []byte) error {
  166. // 1. 打开文件
  167. file, err := os.OpenFile(filePath, os.O_RDWR, 0644)
  168. if err != nil {
  169. return fmt.Errorf("error opening file: %v", err)
  170. }
  171. defer file.Close()
  172. // 2. 获取文件元数据
  173. fileInfo, err := file.Stat()
  174. if err != nil {
  175. return fmt.Errorf("error getting file info: %v", err)
  176. }
  177. fileSize := fileInfo.Size()
  178. // 3. 校验插入位置
  179. if position > fileSize {
  180. return fmt.Errorf("position exceeds file size")
  181. }
  182. // 4. 计算需要移动的数据量
  183. //originalDataLength := fileSize - position
  184. insertLength := int64(len(data))
  185. // 5. 分块移动原始数据(从后往前处理)
  186. //var offset int64 = position
  187. //for offset > 0 {
  188. // 定位读取位置
  189. readPos := position
  190. // 读取块数据
  191. buffer := make([]byte, insertLength)
  192. _, err = file.ReadAt(buffer, readPos)
  193. if err != nil && err != io.EOF {
  194. return fmt.Errorf("read block error: %v", err)
  195. }
  196. sign += 1
  197. fmt.Println("buffer len :", len(buffer), " sign => ", sign)
  198. // 写入新位置
  199. _, err = file.WriteAt(buffer, readPos)
  200. if err != nil {
  201. return fmt.Errorf("write block error: %v", err)
  202. }
  203. fmt.Println("writePos ind :", readPos+int64(len(buffer)))
  204. //}
  205. // 6. 写入新数据
  206. _, err = file.WriteAt(data, position)
  207. if err != nil {
  208. return fmt.Errorf("write data error: %v", err)
  209. }
  210. // 7. 扩展文件大小(如果需要)
  211. //newSize := fileSize + insertLength
  212. //if newSize > fileSize {
  213. // if err := file.Truncate(newSize); err != nil {
  214. // return fmt.Errorf("truncate error: %v", err)
  215. // }
  216. //}
  217. return nil
  218. }
  219. func ToHexBytes(bytes []byte) string {
  220. var hexBytes string
  221. for b := range bytes {
  222. hexBytes = fmt.Sprint(hexBytes, fmt.Sprintf("%02X", bytes[b]))
  223. }
  224. return strings.TrimSpace(hexBytes)
  225. }