os.ReadDir 是 Go 1.16+ 推荐的轻量安全目录遍历方式,返回 fs.DirEntry 切片,仅 Name() 和 IsDir() 不触发 stat 调用,需手动过滤 . 和 ..,出错即终止,容错需改用 filepath.WalkDir。

os.ReadDir 是 Go 1.16+ 推荐的目录遍历方式
它比 os.ReadDir 之前的 filepath.Walk 或 os.Open + Readdir 更轻量、更安全:不递归、不自动解析符号链接、返回 fs.DirEntry 而非完整 os.FileInfo,节省系统调用开销。如果你用的是 Go 1.16 及以上(现在绝大多数项目都满足),直接用 os.ReadDir 就行,不用绕路。
用 os.ReadDir 列出当前目录文件名(不含路径)
这是最常见需求——只要名字,不关心类型或大小。注意 os.ReadDir 返回的是 []fs.DirEntry,每个条目有 Name() 和 IsDir() 方法,但默认不加载完整元数据:
entries, err := os.ReadDir(".")
if err != nil {
log.Fatal(err)
}
for _, entry := range entries {
fmt.Println(entry.Name())
}
-
entry.Name()返回纯文件/目录名,不含路径 - 不会自动跳过
.或..,需要手动过滤:if entry.Name() == "." || entry.Name() == ".." { continue } - 如果只想要普通文件(排除目录),加判断:
if !entry.IsDir() { ... }
os.ReadDir 和 ioutil.ReadDir(已弃用)的区别
ioutil.ReadDir 在 Go 1.16 被标记为 deprecated,它内部调用 os.Open + Readdir,返回 []os.FileInfo,每次都要触发 stat 系统调用。而 os.ReadDir 的 DirEntry 默认只读取目录项基本信息,entry.Info() 才真正调用 stat —— 这意味着:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 如果你只需要文件名或是否为目录,
os.ReadDir明显更快、更省内存 - 如果你需要修改时间、大小等字段,必须显式调用
entry.Info(),但会带来额外开销 - 别混用:不能把
os.ReadDir的结果传给期望[]os.FileInfo的旧函数
处理权限错误或不存在的目录
os.ReadDir 遇到权限不足(如 permission denied)或路径不存在时,会直接返回 error,不会部分成功。这意味着:
立即学习“go语言免费学习笔记(深入)”;
- 它不会像
filepath.Walk那样提供错误回调;出错就中断 - 如果目标路径可能不可读,务必检查
err,尤其在 CLI 工具中,别假设目录一定存在 - 常见错误信息包括:
open /path: permission denied、open /path: no such file or directory - 若需容错遍历(比如跳过无法访问的子目录),得换用
filepath.WalkDir并配合WalkDirFunc处理 error
真正要注意的是:别在循环里反复调用 entry.Info() 却忽略它可能返回 error —— 比如某些文件系统里,符号链接指向无效路径时,entry.Info() 会失败,但 entry.Name() 和 entry.IsDir() 仍可用。

















