在Go中列出目录

在Go中列出目录,go,Go,我一直在想,如何在Go中简单地列出单个目录中的文件和文件夹 我已经找到了,但它会自动进入子目录,这是我不想要的。我所有的其他搜索都没有找到更好的结果 我确信这个功能是存在的,但是很难找到。如果有人知道我应该去哪里找,请告诉我。谢谢。您可以尝试使用io/ioutil软件包中的函数。根据文件: ReadDir读取以dirname命名的目录,并返回已排序目录项的列表 生成的切片包含提供所列方法的os.FileInfo类型。下面是一个基本示例,列出了当前目录中所有内容的名称(包括文件夹,但没有特别标记-

我一直在想,如何在Go中简单地列出单个目录中的文件和文件夹

我已经找到了,但它会自动进入子目录,这是我不想要的。我所有的其他搜索都没有找到更好的结果

我确信这个功能是存在的,但是很难找到。如果有人知道我应该去哪里找,请告诉我。谢谢。

您可以尝试使用
io/ioutil
软件包中的函数。根据文件:

ReadDir读取以dirname命名的目录,并返回已排序目录项的列表

生成的切片包含提供所列方法的
os.FileInfo
类型。下面是一个基本示例,列出了当前目录中所有内容的名称(包括文件夹,但没有特别标记-您可以使用
IsDir()
方法检查项目是否为文件夹):


ioutil.ReadDir
是一个很好的发现,但是如果您单击并查看源代码,就会发现它调用了该方法。如果您对目录顺序没有意见,并且不需要对列表进行排序,那么您只需要使用Readdir方法。

更简单的是,使用
path/filepath

package main    

import (
    "fmt"
    "log"
    "path/filepath"
)

func main() {
    files, err := filepath.Glob("*")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(files) // contains a list of all files in the current directory
}

我们可以使用各种golang标准库函数在文件系统的文件夹中获取文件列表

  • filepath.Walk
  • ioutil.ReadDir
  • os.File.Readdir
  • 使用filepath.Walk
  • path/filepath
    包提供了一种扫描所有文件的简便方法 在目录中,它将自动扫描目录中的每个子目录 目录

  • 使用ioutil.ReadDir

  • ioutil.ReadDir
    读取以dirname命名的目录并返回 按文件名排序的目录项列表

  • 使用os.File.Readdir
  • Readdir读取与文件关联的目录的内容,并 返回最多n个FileInfo值的切片,如 Lstat,按目录顺序。对同一文件的后续调用将 产生更多的文件信息

    基准结果


    从您的描述中获取更多有关此的详细信息,您可能需要的是

    func(f*文件)Readdirnames(n int)(名称[]字符串,错误)

    Readdirnames读取与文件关联的目录的内容,并按目录顺序返回目录中最多n个文件名的片段。对同一文件的后续调用将产生更多的名称


    如果n从Go 1.16开始,您可以使用该函数

    func ReadDir(名称字符串)([]目录项,错误)

    它读取给定目录并返回一个
    DirEntry
    切片,其中包含按文件名排序的目录项

    这是一个乐观函数,因此,当读取目录条目时发生错误时,它会尝试返回一个包含文件名的片段,直到错误发生之前

    package main
    
    import (
        "fmt"
        "log"
        "os"
    )
    
    func main() {
        files, err := os.ReadDir(".")
        if err != nil {
            log.Fatal(err)
        }
    
        for _, file := range files {
            fmt.Println(file.Name())
        }
    }
    
    利息:(2021年第3季度)包括:

    func FileInfoToDirEntry(info FileInfo)DirEntry
    
    FileInfoToDirEntry
    返回从
    info
    返回信息的
    DirEntry

    如果
    info
    为nil,
    FileInfoToDirEntry
    返回nil


    背景 Go 1.16(2021年第1季度)将根据以下内容提出建议:

    //FS提供对分层文件系统的访问。
    //
    //FS接口是文件系统所需的最低实现。
    //文件系统可以实现额外的接口,
    //例如fsutil.ReadFileFS,以提供附加或优化的功能。
    //有关详细信息,请参见io/fsutil。
    类型FS接口{
    //打开打开命名文件。
    //
    //当Open返回错误时,它的类型应为*PathError
    //Op字段设置为“打开”,路径字段设置为名称,
    //以及描述问题的Err字段。
    //
    //Open应拒绝尝试打开不满足以下条件的名称
    //ValidPath(名称),返回*PathError,错误设置为
    //ErrInvalid或ErrNotExist。
    打开(名称字符串)(文件,错误)
    }
    
    这允许:
    见:

    //ReadDir读取与文件f关联的目录的内容
    //并按目录顺序返回DirEntry值的片段。
    //对同一文件的后续调用将在目录中生成稍后的DirEntry记录。
    //
    //如果n>0,ReadDir最多返回n条DirEntry记录。
    //在这种情况下,如果ReadDir返回一个空切片,它将返回一个解释原因的错误。
    //在目录的末尾,错误是io.EOF。
    //
    
    //If n注意
    Glob忽略文件系统错误,例如读取目录时的I/O错误。当模式格式不正确时,唯一可能返回的错误是ErrBadPattern。
    请确保在使用Glob之前了解Glob的功能。这里有最完整的答案。值得注意的是,这个基准测试没有报告内存使用情况或alloc。更快的实现可能会使用更多的内存。测试仪计算机上的CPU内核数也可能会影响/帮助并发
    文件路径.Walk
    。此外,
    filepath.Walk
    支持递归下降,而
    os.File.Readdir
    ioutil.Readdir
    不支持。有人能给我解释一下如何读取/解释基准测试结果吗?@xuiqzy
    ns/op
    =每次操作纳秒,所以越小越好。但是正如@xeoncross所提到的,Walk在并发环境中可能更好,在有大量文件的环境中可能会使用更少的内存“从Go 1.16开始,
    os.ReadDir
    是一个更有效和正确的选择:它返回
    fs.DirEntry
    的列表,而不是
    fs.FileInfo
    ,并且在读取目录中途出错时返回部分结果。”
    
    package main
    
    import (
        "fmt"
        "io/ioutil"
        "log"
        "os"
        "path/filepath"
    )
    
    func main() {
        var (
            root  string
            files []string
            err   error
        )
    
        root := "/home/manigandan/golang/samples"
        // filepath.Walk
        files, err = FilePathWalkDir(root)
        if err != nil {
            panic(err)
        }
        // ioutil.ReadDir
        files, err = IOReadDir(root)
        if err != nil {
            panic(err)
        }
        //os.File.Readdir
        files, err = OSReadDir(root)
        if err != nil {
            panic(err)
        }
    
        for _, file := range files {
            fmt.Println(file)
        }
    }
    
    func FilePathWalkDir(root string) ([]string, error) {
        var files []string
        err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
            if !info.IsDir() {
                files = append(files, path)
            }
            return nil
        })
        return files, err
    }
    
    func IOReadDir(root string) ([]string, error) {
        var files []string
        fileInfo, err := ioutil.ReadDir(root)
        if err != nil {
            return files, err
        }
    
        for _, file := range fileInfo {
            files = append(files, file.Name())
        }
        return files, nil
    }
    
    func OSReadDir(root string) ([]string, error) {
        var files []string
        f, err := os.Open(root)
        if err != nil {
            return files, err
        }
        fileInfo, err := f.Readdir(-1)
        f.Close()
        if err != nil {
            return files, err
        }
    
        for _, file := range fileInfo {
            files = append(files, file.Name())
        }
        return files, nil
    }
    
    file, err := os.Open(path)
    if err != nil {
        return err
    }
    defer file.Close()
    names, err := file.Readdirnames(0)
    if err != nil {
        return err
    }
    fmt.Println(names)
    
    package main
    
    import (
        "fmt"
        "log"
        "os"
    )
    
    func main() {
        files, err := os.ReadDir(".")
        if err != nil {
            log.Fatal(err)
        }
    
        for _, file := range files {
            fmt.Println(file.Name())
        }
    }