ZetCode

Go 查找文件

最后修改时间 2024 年 4 月 11 日

在本文中,我们将介绍如何使用 filepath.Walk 来查找文件。

filepath 包实现了用于操作文件名路径的实用程序例程。

filepath.Walk 遍历文件树,为树中的每个文件或目录(包括根目录)调用指定的函数。该函数将递归地遍历所有子目录。

Go 查找文本文件

在第一个示例中,我们搜索文本文件。

find_text_files.go
package main

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

func main() {

    var files []string

    root := "/home/janbodnar/Documents"

    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {

        if err != nil {

            fmt.Println(err)
            return nil
        }

        if !info.IsDir() && filepath.Ext(path) == ".txt" {
            files = append(files, path)
        }

        return nil
    })

    if err != nil {
        log.Fatal(err)
    }

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

在代码示例中,我们搜索扩展名为 .txt 的文件。

var files []string

匹配的文件存储在 files 切片中。

root := "/home/janbodnar/Documents"

这是我们开始搜索的根目录。

err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {

filepath.Walk 的第一个参数是根目录。第二个参数是 walk 函数;filepath.Walk 调用该函数来访问每个文件或目录。

if err != nil {

    fmt.Println(err)
    return nil
}

如果发生错误,则打印错误,但继续在其他地方搜索。

if !info.IsDir() && filepath.Ext(path) == ".txt" {
    files = append(files, path)
}

如果文件不是目录且扩展名为 .txt,我们将其添加到 files 切片中。

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

最后,我们遍历 files 切片并将所有匹配的文件打印到控制台。

Go 按大小查找文件

在下一个示例中,我们按文件大小查找文件。

findbysize.go
package main

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

var files []string

func VisitFile(path string, info os.FileInfo, err error) error {

    if err != nil {

        fmt.Println(err)
        return nil
    }

    file_size := info.Size()

    if !info.IsDir() && file_size > 1024*1024 {

        files = append(files, path)
    }

    return nil
}

func main() {

    root := "/home/janbodnar/Documents"

    err := filepath.Walk(root, VisitFile)

    if err != nil {
        log.Fatal(err)
    }

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

该示例列出了大小大于 1 MB 的文件。

file_size := info.Size()

使用 Size 方法,我们确定文件的大小(以字节为单位)。

if !info.IsDir() && file_size > 1024*1024 {

    files = append(files, path)
}

如果文件不是目录且其大小大于 1 MB,我们将其添加到 files 切片中。

Go 按修改时间查找文件

在下一个示例中,我们按修改时间查找文件。

findmodif.go
package main

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

func FindFilesAfter(dir string, t time.Time) (files []string, err error) {

    err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {

        if err != nil {

            fmt.Println(err)
            return nil
        }

        if !info.IsDir() && filepath.Ext(path) == ".txt" && info.ModTime().After(t) {
            files = append(files, path)
        }

        return nil
    })

    return
}

func main() {

    root := "/home/janbodnar/Documents"

    t, err := time.Parse("2006-01-02T15:04:05-07:00", "2021-05-01T00:00:00+00:00")

    if err != nil {
        log.Fatal(err)
    }

    files, err := FindFilesAfter(root, t)

    if err != nil {

        log.Fatal(err)
    }

    for _, file := range files {

        fmt.Println(file)
    }
}

我们查找所有在 2021 年 5 月 1 日之后修改过的文本文件。

if !info.IsDir() && filepath.Ext(path) == ".txt" && info.ModTime().After(t) {
    files = append(files, path)
}

ModTime 给出文件的最后修改时间。使用 After 函数,我们检查时间点是否在给定时间之后。

Go 按正则表达式查找文件

在下面的示例中,我们根据正则表达式搜索文件名。

findregex.go
package main

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

var files []string

func VisitFile(path string, info os.FileInfo, err error) error {

    if err != nil {

        fmt.Println(err)
        return nil
    }

    if info.IsDir() || filepath.Ext(path) != ".txt" {

        return nil
    }

    reg, err2 := regexp.Compile("^[la]")

    if err2 != nil {

        return err2
    }

    if reg.MatchString(info.Name()) {

        files = append(files, path)
    }

    return nil
}

func main() {

    err := filepath.Walk("/home/janbodnar/Documents", VisitFile)

    if err != nil {

        log.Fatal(err)
    }

    for _, file := range files {

        fmt.Println(file)
    }
}

在代码示例中,我们搜索以字母 l 或字母 a 开头的文本文件。

reg, err2 := regexp.Compile("^[la]")

我们使用 regexp.Compile 编译正则表达式。

if reg.MatchString(info.Name()) {

    files = append(files, path)
}

如果正则表达式匹配文件名,我们将其添加到 files 切片中。

来源

Go path/filepath 包 - 参考

在本文中,我们使用 filepath.Walk 在 Golang 中搜索文件。

作者

我叫 Jan Bodnar,是一位热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Go 教程