如何使用go遍历目录获取文件列表

简介: 如何使用go遍历目录获取文件列表

通过go遍历目录获取文件列表

Hello大家好呀,这次分享的内容是如何使用Go在文件系统中获取到文件夹中的所有文件列表。

本文将会列举三种方法

by Using:

filepath.Walk
ioutil.ReadDir
os.File.Readdir

使用filepath.Walk

path/filepath 标准库的包提供了便捷的Walk方法,它能自动的扫描子目录,使用起来也很简单

package main
import (
    "fmt"
    "os"
    "path/filepath"
)
func main() {
    var files []string
    root := "/some/folder/to/scan"
    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
        files = append(files, path)
        return nil
    })
    if err != nil {
        panic(err)
    }
    for _, file := range files {
        fmt.Println(file)
    }
}

filepath.Walk 接受一个string指向根目录(root),和一个带有签名(signature)的函数类型WalkFunc

type WalkFunc func(path string, info os.FileInfo, err error) error

这个方法将会文件夹扫描的每一次遍历中被调用。

可以看到另一个变量info的类型是os.FileInfo,这个变量非常重要因为我们从当前的文件(文件夹或者是文件)获取很多有用的信息:文件名,文件大小,模式,更改时间

同时我们也可以避免去处理文件夹通过添加(下边的代码表示不处理文件夹)

if info.IsDir(){
    return nil
}

你还可以排除或者筛选出切片中的文件通过他们的拓展名,可以用filepath.Ext然后传文件路径进去(下边的代码表示不处理带.dat拓展名的文件)

if filepath.Ext(path) == '.dat'{
    return nil
}

我们可以存储文件名而非文件目录通过使用

files = append(files,info.Name())

我们也可以在一个单独的闭包中定义WalkFunc。我们只需要在visit中传递一个指向文件的指针:

package main
import (
    "fmt"
    "log"
    "os"
    "path/filepath"
)
func visit(files *[]string) filepath.WalkFunc {
    return func(path string, info os.FileInfo, err error) error {
        if err != nil {
            log.Fatal(err)
        }
        *files = append(*files, path)
        return nil
    }
}
func main() {
    var files []string
    root := "/some/folder/to/scan"
    err := filepath.Walk(root, visit(&files))
    if err != nil {
        panic(err)
    }
    for _, file := range files {
        fmt.Println(file)
    }
}

使用ioutil.ReadDir

filepath.Walk是很方便但是它会扫描所有子文件夹,缺省情况下,但这有时候不是我们想要的需求

go的标准库还提供了ioutil.ReadDir

ioutil.ReadDir需要一个string类型的文件夹路径然后返回一个os.FileInfo的切片,在上文中提到过。

package main
import (
    "fmt"
    "io/ioutil"
    "log"
)
func main() {
    files, err := ioutil.ReadDir(".")
    if err != nil {
        log.Fatal(err)
    }
    for _, file := range files {
        fmt.Println(file.Name())
    }
}

使用os.File.Readdir

ReadDir内部的实现方式

// ReadDir reads the directory named by dirname and returns
// a list of directory entries sorted by filename.
func ReadDir(dirname string) ([]os.FileInfo, error) {
    f, err := os.Open(dirname)
    if err != nil {
        return nil, err
    }
    list, err := f.Readdir(-1)
    f.Close()
    if err != nil {
        return nil, err
    }
    sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
    return list, nil
}

我们可以看到它只扫描文件夹目录,然后将文件通过名字排序。如果我们不需要这种排序我们可以这样:

package main
import (
    "fmt"
    "log"
    "os"
)
func main() {
    dirname := "."
    f, err := os.Open(dirname)
    if err != nil {
        log.Fatal(err)
    }
    files, err := f.Readdir(-1)
    f.Close()
    if err != nil {
        log.Fatal(err)
    }
    for _, file := range files {
        fmt.Println(file.Name())
    }
}

可以看到我们拆解了原方法的部分,dirname我们可以自己传,只使用Readdir(-1)这个方法去遍历文件夹。说实话这个-1我不是很懂为什么可以这么传,如果有会的大神能不能评论解释一下。


相关文章
|
3月前
|
Go
go语言中遍历映射(map)
go语言中遍历映射(map)
107 8
|
3月前
|
存储 Go 索引
go语言中遍历字符串
go语言中遍历字符串
79 5
|
9天前
|
SQL JSON 关系型数据库
开箱即用的GO后台管理系统 Kratos Admin - 列表查询规则
Kratos Admin 是一个开箱即用的GO后台管理系统,支持通用列表查询请求。通过 `page`、`pageSize`、`query`(AND过滤)、`or`(OR过滤)、`orderBy`(排序)、`noPaging`(不分页)和 `fieldMask`(字段掩码)等参数,灵活配置查询条件。过滤规则遵循Python ORM风格,支持多种查找类型如 `in`、`gte`、`icontains` 等,适用于不同数据库。
18 0
|
2月前
|
Go
go语言for遍历映射(map)
go语言for遍历映射(map)
81 12
|
2月前
|
Go 索引
go语言使用索引遍历
go语言使用索引遍历
45 9
|
2月前
|
Go
go语言for 遍历字符串
go语言for 遍历字符串
44 8
|
2月前
|
存储 Go 索引
go语言使用for循环遍历
go语言使用for循环遍历
68 7
|
3月前
|
Go
go语言中遍历映射同时遍历键和值
go语言中遍历映射同时遍历键和值
34 7
|
3月前
|
Go 索引
go语言遍历字符串
go语言遍历字符串
54 3
|
3月前
|
存储 Go
go语言 遍历映射(map)
go语言 遍历映射(map)
59 2

热门文章

最新文章