在Golang中处理目录扫描和文件列表读取的需求时,ioutil包提供的ReadDir方法是一个常用的选择,它能够快速获取指定目录下的所有文件信息,简化目录遍历的实现流程。

ioutil ReadDir方法基本介绍
ioutil.ReadDir是Go标准库ioutil包中的一个函数,其作用是读取指定目录的所有目录项,返回一个按文件名排序的[]os.FileInfo切片,同时返回可能出现的错误。该方法的函数签名如下:
func ReadDir(dirname string) ([]os.FileInfo, error)
其中dirname参数表示需要扫描的目标目录路径,可以是相对路径也可以是绝对路径。返回的切片中每个元素都包含了对应文件或子目录的详细信息,比如文件名、大小、修改时间、是否为目录等属性。
基础使用示例
下面是一个最简单的使用ReadDir读取目录文件列表的示例,实现读取指定目录下的所有文件并打印文件名:
package main
import (
"fmt"
"io/ioutil"
"log"
)
func main() {
// 指定要扫描的目录路径,这里使用当前目录
dirPath := "./"
// 调用ReadDir方法获取目录下的文件信息
fileInfos, err := ioutil.ReadDir(dirPath)
if err != nil {
log.Fatalf("读取目录失败:%v", err)
}
// 遍历文件信息切片,打印每个文件的名称
fmt.Printf("目录 %s 下的文件列表:n", dirPath)
for _, fileInfo := range fileInfos {
fmt.Println(fileInfo.Name())
}
}
运行上述代码后,会输出当前目录下所有文件和子目录的名称,默认按照文件名的字典序排列。
获取更详细的文件信息
os.FileInfo接口提供了多个方法可以获取文件的详细属性,常用的属性获取方法如下:
Name():返回文件的名称,不包含路径部分Size():返回文件的大小,单位是字节,如果是目录则返回0Mode():返回文件的权限模式和类型信息ModTime():返回文件的最后修改时间IsDir():判断当前项是否为目录,返回布尔值
下面的示例会打印每个文件或目录的详细属性:
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
)
func main() {
dirPath := "./"
fileInfos, err := ioutil.ReadDir(dirPath)
if err != nil {
log.Fatalf("读取目录失败:%v", err)
}
fmt.Printf("%-20s %-10s %-20s %-10sn", "文件名", "大小(字节)", "修改时间", "是否为目录")
for _, fileInfo := range fileInfos {
// 格式化输出文件信息
fmt.Printf("%-20s %-10d %-20v %-10vn",
fileInfo.Name(),
fileInfo.Size(),
fileInfo.ModTime().Format("2006-01-02 15:04:05"),
fileInfo.IsDir(),
)
}
}
递归遍历子目录
ioutil.ReadDir本身只读取指定目录的直接子项,不会递归遍历子目录下的内容。如果需要获取目录下所有层级的文件,需要结合递归逻辑实现。下面的示例实现了递归遍历目录并打印所有文件的路径:
package main
import (
"fmt"
"io/ioutil"
"log"
"path/filepath"
)
// 递归遍历目录的辅助函数
func walkDir(dirPath string) error {
// 读取当前目录的文件列表
fileInfos, err := ioutil.ReadDir(dirPath)
if err != nil {
return err
}
for _, fileInfo := range fileInfos {
// 拼接完整的文件路径
fullPath := filepath.Join(dirPath, fileInfo.Name())
fmt.Println(fullPath)
// 如果是目录,递归遍历
if fileInfo.IsDir() {
if err := walkDir(fullPath); err != nil {
return err
}
}
}
return nil
}
func main() {
targetDir := "./"
err := walkDir(targetDir)
if err != nil {
log.Fatalf("递归遍历目录失败:%v", err)
}
}
注意事项
在使用ioutil.ReadDir时需要注意以下几点:
- 路径参数需要保证正确,如果目录不存在或者没有读取权限,会返回对应的错误,必须进行错误处理
- ioutil包在Go 1.16版本之后已经被逐步废弃,官方推荐使用
os.ReadDir方法替代,os.ReadDir的返回值是[]os.DirEntry,性能更优且功能更完善 - 如果需要过滤特定类型的文件,可以在遍历切片时添加判断逻辑,比如只处理后缀为.txt的文件
如果需要兼容旧版本Go代码,ioutil.ReadDir仍然可以正常使用,新开发的代码建议优先选择os.ReadDir实现目录扫描功能。