2 回答

TA贡献1786条经验 获得超11个赞
首先,你应该使用filepath.WalkDir
Go 1.16 中引入的,它比filepath.Walk
.
Walk 的效率低于 Go 1.16 中引入的 WalkDir,后者避免在每个访问的文件或目录上调用 os.Lstat。
然后,无法将最大深度指定为直接参数。您必须计算WalkDirFunc
.
显然,在文件路径中计算分隔符是一种可接受的策略(并且可以说比其他可能的技巧更简单),因此解决方案可能如下所示:
maxDepth := 2
rootDir := "root"
err := filepath.WalkDir(rootDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
// handle possible path err, just in case...
return err
}
if d.IsDir() && strings.Count(path, string(os.PathSeparator)) > maxDepth {
fmt.Println("skip", path)
return fs.SkipDir
}
// ... process entry
return nil
})
所以dir结构如下:
.
└── root
├── a.txt
├── b.txt
└── root1
├── a.txt
└── root2
├── a.txt
├── b.txt
├── root3
│ └── a.txt
└── root4
并假设root在 depth 0,上面的代码打印上面的代码:
skip root/root1/root2/root3
skip root/root1/root2/root4

TA贡献1963条经验 获得超6个赞
func ControlDeepWalk(basepath string, count int, hard, debug bool) error {
var (
stock = make(map[string][]string)
countBase = 0
correctdirs []string
)
base := filepath.Base(basepath)
dirbase := filepath.Dir(basepath)
countBase = len(strings.Split(filepath.Dir(basepath), "/"))
if debug {
log.Printf("countbase: %v %v\n", strings.Split(filepath.Dir(basepath), "/"), countBase)
log.Printf("base :%v : %v : %v\n", base, dirbase, strings.Split(basepath, "/"))
}
err := filepath.WalkDir(basepath, func(path string, d fs.DirEntry, err error) error {
if err != nil {
if debug {
log.Printf("--error inf walkdir function, exit")
}
return err
}
if d.IsDir() {
if filepath.Dir(path) == filepath.Dir(basepath) {
if debug {
log.Printf("found root directory, skipping %v : %v\n", filepath.Dir(path), filepath.Dir(basepath))
}
} else {
compare := false
if hard {
compare = len(strings.Split(filepath.Dir(path), "/")) == countBase+count
} else {
compare = len(strings.Split(filepath.Dir(path), "/")) <= countBase+count
}
if compare {
if debug {
log.Printf("-found dir: [%v] %v\n", path, d.Name())
}
stock[filepath.Dir(filepath.Join(path, d.Name()))] = []string{}
correctdirs = append(correctdirs, filepath.Dir(filepath.Join(path, d.Name())))
}
}
} else {
fdir, ffile := filepath.Split(path)
for _, x := range correctdirs {
if x == filepath.Dir(fdir) {
if debug {
log.Printf("-found file:%v : %v %v %v \n", d.Name(), path, fdir, ffile)
}
stock[x] = append(stock[x], d.Name())
}
}
}
return nil
})
if debug {
for k, v := range stock {
log.Printf("%v : %v \n", k, v)
}
log.Printf("%v\n", stock)
}
return err
}
func main() {
p := "/backup/backuper/test"
count := 2
_ = ControlDeepWalk(p, count, false, true)
}
- 2 回答
- 0 关注
- 264 浏览
添加回答
举报