main.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. package main
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "file-manger-server/config"
  6. "file-manger-server/db"
  7. "file-manger-server/server"
  8. "file-manger-server/service"
  9. "fmt"
  10. "io/fs"
  11. "os"
  12. "path/filepath"
  13. "strings"
  14. "sync"
  15. )
  16. func main() {
  17. //初始化
  18. config.ReadConfig()
  19. db.Open()
  20. //tcp服务器启动
  21. go server.Run()
  22. //gin服务器启动
  23. service.RunGin()
  24. os.Exit(0) // 确保程序退出
  25. //TestHandlerReceiveFile()
  26. //TestFiles()
  27. }
  28. func TestHandlerReceiveFile() {
  29. bytes := []byte{
  30. 0x00,
  31. }
  32. for i := 0; i < 32; i++ {
  33. bytes = append(bytes, byte(i+3))
  34. }
  35. var fileName = "test.txt"
  36. //文件名长度
  37. bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(fileName)))
  38. //文件名
  39. bytes = append(bytes, []byte(fileName)...)
  40. //文件大小
  41. bytes = binary.BigEndian.AppendUint64(bytes, uint64(10))
  42. var path = "./file/" + fileName
  43. bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(path)))
  44. //文件路径
  45. bytes = append(bytes, []byte(path)...)
  46. //分片大小
  47. bytes = binary.BigEndian.AppendUint32(bytes, uint32(0))
  48. //创建时间
  49. bytes = binary.BigEndian.AppendUint64(bytes, uint64(999))
  50. //修改时间
  51. bytes = binary.BigEndian.AppendUint64(bytes, uint64(9999))
  52. //最后访问时间
  53. bytes = binary.BigEndian.AppendUint64(bytes, uint64(99999))
  54. bytes = append(bytes, []byte("1234567890中文")...)
  55. server.HandlerReceiveFile(nil, bytes)
  56. }
  57. func TestBigFileSend() {
  58. //var str = "\tif err != nil {\n\t\treturn errors.New(\"FileUser transactionId is not found\")\n\t}\n\tif fileUser.UserId == 0 {\n\t\treturn errors.New(\"FileUser userId is not found\")\n\t}"
  59. //var data = []byte(str + str + str + str + str + str + "\t//config.ReadConfig()\n\t//db.Open()\n\t////server.Run()\n\t// server")
  60. ////切片1
  61. //{
  62. // bytes := []byte{
  63. // 0x00,
  64. // }
  65. // for i := 0; i < 32; i++ {
  66. // bytes = append(bytes, byte(i+3))
  67. // }
  68. // var fileName = "test.txt"
  69. // //文件名长度
  70. // bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(fileName)))
  71. // //文件名
  72. // bytes = append(bytes, []byte(fileName)...)
  73. // //文件大小
  74. // bytes = binary.BigEndian.AppendUint64(bytes, uint64(1024*2+8))
  75. // var path = "file/" + fileName
  76. // bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(path)))
  77. // //文件路径
  78. // bytes = append(bytes, []byte(path)...)
  79. // //分片大小
  80. // bytes = binary.BigEndian.AppendUint32(bytes, uint32(2))
  81. // //创建时间
  82. // bytes = binary.BigEndian.AppendUint64(bytes, uint64(999))
  83. // //修改时间
  84. // bytes = binary.BigEndian.AppendUint64(bytes, uint64(9999))
  85. // //最后访问时间
  86. // bytes = binary.BigEndian.AppendUint64(bytes, uint64(99999))
  87. // server.HandlerReceiveFile(nil, bytes)
  88. //}
  89. //{
  90. // //切片2
  91. // bytes := []byte{
  92. // 0x01,
  93. // }
  94. // for i := 0; i < 32; i++ {
  95. // bytes = append(bytes, byte(i+3))
  96. // }
  97. // var fileName = "test.txt"
  98. // //切片id
  99. // bytes = binary.BigEndian.AppendUint32(bytes, uint32(0))
  100. // var path = "file/" + fileName
  101. // bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(path)))
  102. // //文件路径
  103. // bytes = append(bytes, []byte(path)...)
  104. // fmt.Println("=================================")
  105. // fmt.Println("data len : ", len(data))
  106. // fmt.Println("=================================")
  107. // bytes = append(bytes, data...)
  108. // server.HandlerReceiveFile(nil, bytes)
  109. //}
  110. //
  111. //{
  112. // //切片4
  113. // bytes := []byte{
  114. // 0x01,
  115. // }
  116. // for i := 0; i < 32; i++ {
  117. // bytes = append(bytes, byte(i+3))
  118. // }
  119. // var fileName = "test.txt"
  120. // //切片id
  121. // bytes = binary.BigEndian.AppendUint32(bytes, uint32(2))
  122. // var path = "file/" + fileName
  123. // bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(path)))
  124. // //文件路径
  125. // bytes = append(bytes, []byte(path)...)
  126. // var end = "\n| end |"
  127. // bytes = append(bytes, []byte(end)...)
  128. //
  129. // fmt.Println("=================================")
  130. // fmt.Println("end len : ", len(end))
  131. // fmt.Println("=================================")
  132. // server.HandlerReceiveFile(nil, bytes)
  133. //}
  134. //{
  135. // //切片2
  136. // bytes := []byte{
  137. // 0x01,
  138. // }
  139. // for i := 0; i < 32; i++ {
  140. // bytes = append(bytes, byte(i+3))
  141. // }
  142. // var fileName = "test.txt"
  143. // //切片id
  144. // bytes = binary.BigEndian.AppendUint32(bytes, uint32(1))
  145. // var path = "file/" + fileName
  146. // bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(path)))
  147. // //文件路径
  148. // bytes = append(bytes, []byte(path)...)
  149. // fmt.Println("=================================")
  150. // fmt.Println("data len : ", len(data))
  151. // fmt.Println("=================================")
  152. // bytes = append(bytes, data...)
  153. // server.HandlerReceiveFile(nil, bytes)
  154. //}
  155. {
  156. bytes := []byte{
  157. 0x00,
  158. }
  159. for i := 0; i < 32; i++ {
  160. bytes = append(bytes, byte(i+3))
  161. }
  162. var fileName = "testtxt"
  163. //文件名长度
  164. bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(fileName)))
  165. //文件名
  166. bytes = append(bytes, []byte(fileName)...)
  167. //文件大小
  168. bytes = binary.BigEndian.AppendUint64(bytes, uint64(0xFFFFFFFFFFFFFFFF))
  169. var path = "file/" + fileName
  170. bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(path)))
  171. //文件路径
  172. bytes = append(bytes, []byte(path)...)
  173. //分片大小
  174. bytes = binary.BigEndian.AppendUint32(bytes, uint32(0))
  175. //创建时间
  176. bytes = binary.BigEndian.AppendUint64(bytes, uint64(1999))
  177. //修改时间
  178. bytes = binary.BigEndian.AppendUint64(bytes, uint64(19999))
  179. //最后访问时间
  180. bytes = binary.BigEndian.AppendUint64(bytes, uint64(199999))
  181. server.HandlerReceiveFile(nil, bytes)
  182. }
  183. }
  184. func TestFiles() {
  185. info, err := GetPathInfo("D:\\")
  186. if err != nil {
  187. panic(err)
  188. }
  189. heavy, err := GoHeavy(info)
  190. if err != nil {
  191. panic(err)
  192. }
  193. fmt.Println(heavy.Dirs)
  194. }
  195. type PathInfo struct {
  196. Dirs []string // 目录路径(包含所有层级)
  197. Files []string // 文件路径
  198. }
  199. var pathPool = sync.Pool{
  200. New: func() interface{} {
  201. return &PathInfo{
  202. Dirs: make([]string, 0, 1024), // 预分配容量
  203. Files: make([]string, 0, 4096),
  204. }
  205. },
  206. }
  207. func GoHeavy(info *PathInfo) (PathInfo, error) {
  208. m := make(map[string]bool)
  209. for i := range info.Files {
  210. path := info.Files[i]
  211. lastIndex := strings.LastIndex(path, "/")
  212. if lastIndex == -1 {
  213. lastIndex = strings.LastIndex(path, "\\")
  214. }
  215. if lastIndex == -1 {
  216. continue
  217. }
  218. //if _, ok := m[path[:lastIndex]]; !ok {
  219. // fmt.Println(path[:lastIndex])
  220. //}
  221. m[path[:lastIndex]] = true
  222. }
  223. var dirs = make([]string, 0, len(m))
  224. fmt.Println(len(info.Dirs))
  225. for i := range info.Dirs {
  226. path := info.Dirs[i]
  227. if !m[path] {
  228. fmt.Println(info.Dirs[i])
  229. dirs = append(dirs, info.Dirs[i])
  230. }
  231. }
  232. info.Dirs = dirs
  233. return *info, nil
  234. }
  235. func GetPathInfo(root string) (*PathInfo, error) {
  236. //获取文件名
  237. index := strings.LastIndex(root, "/")
  238. if index == -1 {
  239. index = strings.LastIndex(root, "\\")
  240. }
  241. //RootFileName := ""
  242. //if index == -1 {
  243. // RootFileName = root
  244. //} else {
  245. // RootFileName = root[:index+1]
  246. //}
  247. // 复用对象减少内存分配[9](@ref)
  248. info := pathPool.Get().(*PathInfo)
  249. // 路径有效性校验[5,6](@ref)
  250. root = filepath.Clean(root)
  251. stat, err := os.Stat(root)
  252. if err != nil {
  253. if errors.Is(err, fs.ErrNotExist) {
  254. return nil, &os.PathError{Op: "stat", Path: root, Err: err} // 增强错误信息[8](@ref)
  255. }
  256. return nil, err
  257. }
  258. // 文件直接返回[4](@ref)
  259. if !stat.IsDir() {
  260. info.Files = append(info.Files, root)
  261. return info, nil
  262. }
  263. // 使用WalkDir优化遍历性能[4,9](@ref)
  264. err = filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
  265. if err != nil {
  266. // 处理遍历错误但继续执行[7](@ref)
  267. if errors.Is(err, fs.ErrPermission) {
  268. return nil // 跳过权限错误
  269. }
  270. return err
  271. }
  272. // 排除根目录自身
  273. if path == root {
  274. return nil
  275. }
  276. // 动态扩容检测[9](@ref)
  277. if len(info.Dirs)+len(info.Files) > 1e8 {
  278. return errors.New("超出内存安全阈值(1,000,000条路径)")
  279. }
  280. //fmt.Println(path[len(RootFileName):])
  281. if d.IsDir() {
  282. info.Dirs = append(info.Dirs, path)
  283. } else {
  284. info.Files = append(info.Files, path)
  285. }
  286. return nil
  287. })
  288. if err != nil {
  289. return nil, &os.PathError{Op: "walk", Path: root, Err: err} // 错误包装[6](@ref)
  290. }
  291. return info, nil
  292. }
  293. // 流式处理版本(适用于超大数据集)
  294. func StreamPathInfo(root string) (<-chan string, <-chan error) {
  295. paths := make(chan string, 1000)
  296. errs := make(chan error, 1)
  297. go func() {
  298. defer close(paths)
  299. defer close(errs)
  300. err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
  301. if err != nil {
  302. return err
  303. }
  304. if path != root {
  305. select {
  306. case paths <- path:
  307. default:
  308. return errors.New("消费者处理过慢")
  309. }
  310. }
  311. return nil
  312. })
  313. if err != nil {
  314. errs <- &os.PathError{Op: "stream", Path: root, Err: err}
  315. }
  316. }()
  317. return paths, errs
  318. }