猿问

如何在 Golang 中的 filepath.walk() func 中为目录的递归迭代设置深度?

我想在包含各种子目录的目录中搜索特定类型的文件。我filepath.walk()在 Golang 中为此使用。但是,我不想递归迭代超出我知道该文件不存在的最大深度。

Golang 中有没有这样的预建函数/库?


ibeautiful
浏览 266回答 2
2回答

Qyouu

首先,你应该使用filepath.WalkDirGo 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/root3skip root/root1/root2/root4

神不在的星期二

func ControlDeepWalk(basepath string, count int, hard, debug bool) error {&nbsp; &nbsp; var (&nbsp; &nbsp; &nbsp; &nbsp; stock&nbsp; &nbsp; &nbsp; &nbsp;= make(map[string][]string)&nbsp; &nbsp; &nbsp; &nbsp; countBase&nbsp; &nbsp;= 0&nbsp; &nbsp; &nbsp; &nbsp; correctdirs []string&nbsp; &nbsp; )&nbsp; &nbsp; base := filepath.Base(basepath)&nbsp; &nbsp; dirbase := filepath.Dir(basepath)&nbsp; &nbsp; countBase = len(strings.Split(filepath.Dir(basepath), "/"))&nbsp; &nbsp; if debug {&nbsp; &nbsp; &nbsp; &nbsp; log.Printf("countbase: %v&nbsp; %v\n", strings.Split(filepath.Dir(basepath), "/"), countBase)&nbsp; &nbsp; &nbsp; &nbsp; log.Printf("base :%v : %v : %v\n", base, dirbase, strings.Split(basepath, "/"))&nbsp; &nbsp; }&nbsp; &nbsp; err := filepath.WalkDir(basepath, func(path string, d fs.DirEntry, err error) error {&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if debug {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.Printf("--error inf walkdir function, exit")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return err&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if d.IsDir() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if filepath.Dir(path) == filepath.Dir(basepath) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if debug {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.Printf("found root directory, skipping&nbsp; %v :&nbsp; %v\n", filepath.Dir(path), filepath.Dir(basepath))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compare := false&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if hard {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compare = len(strings.Split(filepath.Dir(path), "/")) == countBase+count&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compare = len(strings.Split(filepath.Dir(path), "/")) <= countBase+count&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if compare {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if debug {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.Printf("-found dir: [%v] %v\n", path, d.Name())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stock[filepath.Dir(filepath.Join(path, d.Name()))] = []string{}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; correctdirs = append(correctdirs, filepath.Dir(filepath.Join(path, d.Name())))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fdir, ffile := filepath.Split(path)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for _, x := range correctdirs {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if x == filepath.Dir(fdir) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if debug {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.Printf("-found file:%v&nbsp; : %v&nbsp; &nbsp;%v&nbsp; %v \n", d.Name(), path, fdir, ffile)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stock[x] = append(stock[x], d.Name())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return nil&nbsp; &nbsp; })&nbsp; &nbsp; if debug {&nbsp; &nbsp; &nbsp; &nbsp; for k, v := range stock {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.Printf("%v : %v \n", k, v)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; log.Printf("%v\n", stock)&nbsp; &nbsp; }&nbsp; &nbsp; return err}func main() {&nbsp; &nbsp; p := "/backup/backuper/test"&nbsp; &nbsp; count := 2&nbsp; &nbsp; _ = ControlDeepWalk(p, count, false, true)}
随时随地看视频慕课网APP

相关分类

Go
我要回答