推荐用 os.ReadDir 读单层目录(Go 1.16+ 替代 ioutil.ReadDir),高效轻量;递归遍历用 filepath.Walk,自动深度扫描并支持回调过滤;注意权限错误处理、隐藏文件判断及跨平台路径拼接。

使用 Go 语言遍历目录并读取文件列表,最常用且推荐的方式是 ioutil.ReadDir(Go 1.16+ 已弃用,应改用 os.ReadDir)或更底层的 filepath.Walk。下面直接讲清楚怎么用、该选哪个、注意什么。
用 os.ReadDir 读取单层目录内容(推荐)
os.ReadDir 是 Go 1.16 引入的轻量级替代方案,比旧版 ioutil.ReadDir 更高效,不加载完整文件信息(如内容),只读取目录项元数据。
- 它返回
[]fs.DirEntry,每个条目支持快速判断是否为目录或文件(.IsDir()) - 不递归,只读当前目录一级
- 按文件系统顺序返回,如需排序需自行调用
sort.Slice
示例:
package main
import (
"fmt"
"os"
)
func main() {
entries, err := os.ReadDir("./mydir")
if err != nil {
panic(err)
}
for _, entry := range entries {
if entry.IsDir() {
fmt.Printf("DIR %s\n", entry.Name())
} else {
fmt.Printf("FILE %s\n", entry.Name())
}
}
}
用 filepath.Walk 递归遍历整个目录树
当需要深度扫描子目录(比如查找所有 .go 文件),用 filepath.Walk 最直接。它自动递归,并对每个路径调用回调函数。
立即学习“go语言免费学习笔记(深入)”;
- 回调函数签名:
func(path string, info fs.FileInfo, err error) error - 可通过
info.IsDir()区分目录/文件;若为目录且想跳过其子项,可返回filepath.SkipDir - 注意:它会进入符号链接指向的目录(除非你手动跳过)
示例:列出所有 .txt 文件路径
err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && filepath.Ext(path) == ".txt" {
fmt.Println(path)
}
return nil
})
避免踩坑的几个关键点
-
ioutil.ReadDir在 Go 1.16+ 已被标记为 deprecated,新项目请统一用os.ReadDir -
os.ReadDir和filepath.Walk都不会自动处理权限错误(如无读取权限的子目录),遇到时回调中err != nil,需显式检查并决定是否继续 - 如果要过滤隐藏文件(以
.开头),需手动判断entry.Name()[0] == '.'(注意空名和 Windows 兼容性) - 路径拼接务必用
filepath.Join,别用字符串 +,否则跨平台出错
简单封装一个安全的递归文件收集函数
如果你常做类似操作,可以封装一个带错误处理和扩展名过滤的小工具:
func WalkFiles(root string, exts ...string) ([]string, error) {
var files []string
extSet := make(map[string]bool)
for _, e := range exts {
extSet[strings.ToLower(e)] = true
}
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil // 忽略权限错误,继续遍历
}
if !info.IsDir() {
ext := strings.ToLower(filepath.Ext(path))
if len(exts) == 0 || extSet[ext] {
files = append(files, path)
}
}
return nil
})
return files, err
}
调用:goFiles, _ := WalkFiles("./src", ".go")
基本上就这些。不用第三方库,标准库已足够健壮。选 os.ReadDir 做单层,选 filepath.Walk 做递归,注意错误处理和路径安全,就稳了。










