为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
ibeautiful 2022-11-08 16:24:13
我想在包含各种子目录的目录中搜索特定类型的文件。我filepath.walk()在 Golang 中为此使用。但是,我不想递归迭代超出我知道该文件不存在的最大深度。Golang 中有没有这样的预建函数/库?
查看完整描述

2 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

首先,你应该使用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/root3

skip root/root1/root2/root4


查看完整回答
反对 回复 2022-11-08
?
神不在的星期二

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)


}


查看完整回答
反对 回复 2022-11-08
  • 2 回答
  • 0 关注
  • 264 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号