Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File 递归地在目录中查找文件_File_Search_Recursion_Go - Fatal编程技术网

File 递归地在目录中查找文件

File 递归地在目录中查找文件,file,search,recursion,go,File,Search,Recursion,Go,我希望递归地在一个目录(包括子目录)中查找与特定模式匹配的所有文件。我编写了代码来实现这一点: libRegEx, e := regexp.Compile("^.+\\.(dylib)$") if e != nil { log.Fatal(e) } files, err := ioutil.ReadDir("/usr/lib") if err != nil { log.Fatal(err) } for _, f := range files { if libRegEx

我希望递归地在一个目录(包括子目录)中查找与特定模式匹配的所有文件。我编写了代码来实现这一点:

libRegEx, e := regexp.Compile("^.+\\.(dylib)$")
if e != nil {
    log.Fatal(e)
}

files, err := ioutil.ReadDir("/usr/lib")
if err != nil {
    log.Fatal(err)
}

for _, f := range files {
    if libRegEx.MatchString(f.Name()) {
        println(f.Name())
    }
}

不幸的是,它只在
/usr/bin
中搜索,但我还想在其子目录中搜索匹配项。我怎样才能做到这一点?谢谢。

标准库的
文件路径
包中包含的正是出于此目的:“Walk遍历根目录下的文件树,为树中的每个文件或目录调用walkFn,包括根目录。”例如:

libRegEx, e := regexp.Compile("^.+\\.(dylib)$")
if e != nil {
    log.Fatal(e)
}

e = filepath.Walk("/usr/lib", func(path string, info os.FileInfo, err error) error {
    if err == nil && libRegEx.MatchString(info.Name()) {
        println(info.Name())
    }
    return nil
})
if e != nil {
    log.Fatal(e)
}

您可以使用以下代码使用目录中的所有文件:

files, err := ioutil.ReadDir(dirPath)
check(err)

for _, file := range files {
    fmt.Println(dirPath + file.Name())
}

代码使用
io/ioutil
包读取给定目录中的所有文件,然后循环打印这些文件的名称。

如果要查找不使用walk的文件,我发现

尽管使用了字符串,但主要的递归算法似乎还是有效的。它基本上是下面的代码,让我想起了合并排序和其他递归算法:

func processed(fileName string, processedDirectories []string) bool {
    for i := 0; i < len(processedDirectories); i++ {
        if processedDirectories[i] != fileName {
            continue
        }
        return true
    }
    return false
}

func listDirContents(path string, dirs []string) {
    files, _ := ioutil.ReadDir(path)

    for _, f := range files {
        var newPath string
        if path != "/" {
            newPath = fmt.Sprintf("%s/%s", path, f.Name())
        } else {
            newPath = fmt.Sprintf("%s%s", path, f.Name())
        }

        if f.IsDir() {
            if !processed(newPath, dirs) {
                dirs = append(dirs, newPath)
                listDirContents(newPath, dirs)
            }
        } else {
            fmt.Println(newPath)
        }
    }
}
func-processed(文件名字符串,processedDirectories[]字符串)bool{
对于i:=0;i
它实际上打印从提供的目录开始的所有找到的路径,并包括所有子目录。因此,您必须检查路径是否包含目标字符串,而不是仅使用
fmt.Println()
语句打印路径

find
命令进行对比后,它在大约.8秒内扫描了我的
/home
目录。。。
find
命令找到了相同的文件,但只花了大约.3s(比上述算法快了整整.5s)。

从Go 1.16(2021年2月)开始,您可以使用
filepath.WalkDir

package main

import (
   "io/fs"
   "path/filepath"
)

func walk(s string, d fs.DirEntry, e error) error {
   if e != nil { return e }
   if ! d.IsDir() {
      println(s)
   }
   return nil
}

func main() {
   filepath.WalkDir("..", walk)
}

使用。这不起作用。在
dirPath
中只能找到文件/dir,而不是所有文件。您应该更新答案以使用Go 1.16中提供的更高效的filepath.WalkDir功能。