Go语言如何遍历目录_ioutil ReadDir与os ReadDir用法

Go 1.16+ 应使用 os.ReadDir 替代已移除的 ioutil.ReadDir;它返回轻量级 fs.DirEntry,需显式调用 Info() 获取完整元数据;递归遍历应优先选用 filepath.WalkDir。

go语言如何遍历目录_ioutil readdir与os readdir用法

Go 1.16+ 应该用 os.ReadDirioutil.ReadDir 已被移除(它在 Go 1.16 被彻底弃用,且早在 Go 1.15 就已标记为 deprecated)。

为什么不能用 ioutil.ReadDir

ioutil 包在 Go 1.16 中被整体废弃,所有功能迁入 ioos 等标准包。试图使用 ioutil.ReadDir 会直接报错:

undefined: ioutil.ReadDir

这不是版本兼容问题,而是 API 移除 —— 即使你用 Go 1.15,也应避免新代码中使用它。

os.ReadDir 返回 []fs.DirEntry,不是 []os.FileInfo

os.ReadDir 返回的是轻量级的 fs.DirEntry 接口,它只保证提供文件名和是否为目录等基础信息,不强制读取完整元数据(比如修改时间、大小),因此比旧版 os.ReadDir(返回 []os.FileInfo)更快、更省内存。

立即学习go语言免费学习笔记(深入)”;

如果你需要完整文件信息(如 ModTime()Size()),得显式调用 .Info()

entries, err := os.ReadDir("/path")
if err != nil {
    log.Fatal(err)
}
for _, entry := range entries {
    info, err := entry.Info() // 这里才触发系统调用读取完整 stat
    if err != nil {
        log.Printf("failed to get info for %s: %v", entry.Name(), err)
        continue
    }
    fmt.Printf("%s, size: %d, isDir: %t/n", entry.Name(), info.Size(), info.IsDir())
}

常见误操作:直接对 entry 调用 entry.Size()entry.ModTime() —— 这些方法不存在,fs.DirEntry 只有 Name()IsDir()Type()Info()

Detect GPT

Detect GPT

一个Chrome插件,检测您浏览的页面是否包含人工智能生成的内容

下载

递归遍历推荐用 filepath.WalkDir,不是手写循环

单纯一层目录用 os.ReadDir 足够;但要递归遍历(类似 find . -type f),优先选 filepath.WalkDir —— 它内部使用 os.ReadDir,支持按需跳过子树、错误恢复、且不会因深层嵌套导致溢出。

关键点:

  • filepath.WalkDir回调函数接收 fs.DirEntry,同样需调用 .Info() 获取完整信息
  • 返回 filepath.SkipDir 可跳过当前目录(不进入其子目录)
  • 遇到权限错误等,不会中断整个遍历,而是继续处理其他路径

示例:只打印所有普通文件路径

err := filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error {
    if err != nil {
        return nil // 忽略访问错误(如 permission denied)
    }
    if !d.IsDir() {
        fmt.Println(path)
    }
    return nil
})
if err != nil {
    log.Fatal(err)
}

兼容旧代码?别硬套,重写成本很低

如果老项目还在用 os.Stat + os.ReadDir(返回 []os.FileInfo),不要试图“兼容”两种接口。直接替换为 os.ReadDir + 按需 .Info() 即可 —— 大多数场景下,你其实并不需要每项的完整 os.FileInfo,只判断是否为目录或获取文件名就够了。

真正容易被忽略的是:递归遍历时,filepath.WalkDir 的错误处理粒度比 filepath.Walk 更细,且默认不 panic;而很多人仍习惯性用已废弃的 filepath.Walk(它底层用 os.Lstat + os.Readdir,性能较差且无法跳过子树)。

https://www.php.cn/faq/2010239.html

发表回复

Your email address will not be published. Required fields are marked *