UploadFileHandler.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package server
  2. import (
  3. "errors"
  4. "fmt"
  5. "io/fs"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "sync"
  11. )
  12. type PathInfo struct {
  13. Dirs []string // 目录路径(包含所有层级)
  14. Files []string // 文件路径
  15. }
  16. var pathPool = sync.Pool{
  17. New: func() interface{} {
  18. return &PathInfo{
  19. Dirs: make([]string, 0, 1024), // 预分配容量
  20. Files: make([]string, 0, 4096),
  21. }
  22. },
  23. }
  24. func GetPathInfo(root string) (*PathInfo, error) {
  25. //获取文件名
  26. index := strings.LastIndex(root, "/")
  27. if index == -1 {
  28. index = strings.LastIndex(root, "\\")
  29. }
  30. // 复用对象减少内存分配[9](@ref)
  31. info := pathPool.Get().(*PathInfo)
  32. // 路径有效性校验[5,6](@ref)
  33. root = filepath.Clean(root)
  34. stat, err := os.Stat(root)
  35. if err != nil {
  36. if errors.Is(err, fs.ErrNotExist) {
  37. return nil, &os.PathError{Op: "stat", Path: root, Err: err} // 增强错误信息[8](@ref)
  38. }
  39. return nil, err
  40. }
  41. // 文件直接返回[4](@ref)
  42. if !stat.IsDir() {
  43. info.Files = append(info.Files, root)
  44. return info, nil
  45. }
  46. // 使用WalkDir优化遍历性能[4,9](@ref)
  47. err = filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
  48. if err != nil {
  49. // 处理遍历错误但继续执行[7](@ref)
  50. if errors.Is(err, fs.ErrPermission) {
  51. return nil // 跳过权限错误
  52. }
  53. return err
  54. }
  55. // 排除根目录自身
  56. if path == root {
  57. return nil
  58. }
  59. // 动态扩容检测[9](@ref)
  60. if len(info.Dirs)+len(info.Files) > 1e8 {
  61. return errors.New("超出内存安全阈值(1,000,000条路径)")
  62. }
  63. //fmt.Println(path[len(RootFileName):])
  64. if d.IsDir() {
  65. info.Dirs = append(info.Dirs, path)
  66. } else {
  67. info.Files = append(info.Files, path)
  68. }
  69. return nil
  70. })
  71. if err != nil {
  72. return nil, &os.PathError{Op: "walk", Path: root, Err: err} // 错误包装[6](@ref)
  73. }
  74. return info, nil
  75. }
  76. type FileHandler struct{}
  77. func (handler FileHandler) ReadFileToCommand(filePath string) {
  78. _, err := GetPathInfo(filePath)
  79. if err != nil {
  80. fmt.Println(err)
  81. }
  82. }
  83. func (handler FileHandler) CreateCommand(path string) error {
  84. // 获取文件信息
  85. fileInfo, err := os.Stat(path)
  86. if err != nil {
  87. return fmt.Errorf("路径获取失败: %v", err)
  88. }
  89. // 判断文件类型
  90. if fileInfo.IsDir() {
  91. // 处理目录
  92. fmt.Printf("文件夹内容 [%s]:\n", path)
  93. files, err := ioutil.ReadDir(path)
  94. if err != nil {
  95. return fmt.Errorf("目录读取失败: %v", err)
  96. }
  97. for _, f := range files {
  98. fmt.Println(f.Name())
  99. }
  100. } else {
  101. // 处理文件
  102. fmt.Printf("文件内容 [%s]:\n", path)
  103. data, err := ioutil.ReadFile(path)
  104. if err != nil {
  105. return fmt.Errorf("文件读取失败: %v", err)
  106. }
  107. // 打印前512字节的十六进制预览
  108. maxPreview := 512
  109. if len(data) < maxPreview {
  110. maxPreview = len(data)
  111. }
  112. fmt.Printf("大小: %d 字节\n", len(data))
  113. fmt.Printf("前%d字节预览(HEX):\n%x", maxPreview, data[:maxPreview])
  114. }
  115. return nil
  116. }
  117. func (handler FileHandler) ParsingByteArray() {}