在Golang的标准库中,ioutil包提供了很多实用的I/O操作工具,其中ReadDir方法可以方便地读取指定目录下的所有文件信息,不需要开发者手动处理底层的目录读取细节,大幅降低了目录遍历的实现成本。

ioutil.ReadDir基本用法
ioutil.ReadDir的函数签名如下:
func ReadDir(dirname string) ([]os.FileInfo, error)
该方法接收一个目录路径字符串作为参数,返回两个值,第一个是os.FileInfo类型的切片,包含了目录下所有文件的元信息,第二个是错误信息,如果读取目录失败会返回对应的错误。
下面是一个最基础的使用示例,读取当前目录下的所有文件并打印文件名:
package main
import (
"fmt"
"io/ioutil"
"log"
)
func main() {
// 指定要读取的目录路径,这里使用当前目录
dirPath := "./"
// 调用ReadDir方法获取文件列表
fileInfos, err := ioutil.ReadDir(dirPath)
if err != nil {
log.Fatalf("读取目录失败: %v", err)
}
// 遍历文件信息切片
for _, fileInfo := range fileInfos {
// 打印文件名
fmt.Println(fileInfo.Name())
}
}
FileInfo结构体常用字段
返回的os.FileInfo接口包含了文件的多种元信息,常用的字段和方法如下:
- Name():返回文件的名称,不包含路径前缀
- Size():返回文件的大小,单位是字节,如果是目录则返回0
- Mode():返回文件的权限模式和类型信息
- ModTime():返回文件的最后修改时间
- IsDir():判断当前文件是否是目录,返回布尔值
筛选特定类型的文件
实际开发中经常需要筛选出目录下的特定类型文件,比如只获取所有的.go文件,或者只获取普通文件排除目录,下面的示例演示了如何筛选当前目录下的所有Go文件:
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
)
func main() {
dirPath := "./"
fileInfos, err := ioutil.ReadDir(dirPath)
if err != nil {
log.Fatalf("读取目录失败: %v", err)
}
fmt.Println("当前目录下的Go文件列表:")
for _, fileInfo := range fileInfos {
// 判断是否是目录,排除目录
if fileInfo.IsDir() {
continue
}
// 判断文件名是否以.go结尾
if strings.HasSuffix(fileInfo.Name(), ".go") {
fmt.Printf("文件名: %s, 大小: %d字节, 修改时间: %vn", fileInfo.Name(), fileInfo.Size(), fileInfo.ModTime())
}
}
}
读取指定路径的目录文件
ReadDir也支持读取绝对路径或者其他指定路径的目录,比如读取系统的临时目录:
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
)
func main() {
// 获取系统临时目录路径
tmpDir := os.TempDir()
fmt.Printf("系统临时目录路径: %sn", tmpDir)
fileInfos, err := ioutil.ReadDir(tmpDir)
if err != nil {
log.Fatalf("读取临时目录失败: %v", err)
}
fmt.Println("临时目录下的前5个文件:")
// 只打印前5个文件信息
for i, fileInfo := range fileInfos {
if i >= 5 {
break
}
fmt.Printf("%d. %sn", i+1, fileInfo.Name())
}
}
注意事项
需要注意的是,在Go 1.16版本之后,ioutil包中的很多方法都被标记为废弃,ReadDir方法推荐使用os包的ReadDir方法替代,后者的返回值是fs.DirEntry类型,性能更优且功能更完善。如果是使用较新版本的Go开发,建议优先选择os.ReadDir。如果使用的是旧版本Go,ioutil.ReadDir依然是稳定可用的,上述示例在Go 1.15及之前的版本都可以正常运行。另外使用ReadDir时需要确保传入的目录路径存在且有读取权限,否则会返回权限错误或者路径不存在的错误。