main.go 8.4 KB

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