在用Golang遍历一个目录下的所有文件是,可以使用 io/ioutil
包的 ReadDir
方法。ReadDir
方法返回的是一个 os.FileInfo
类型的切片,结构如下:
type FileInfo interface { Name() string // 文件名 Size() int64 // 普通文件返回文件大小;其他文件的返回值根据系统有所不同 Mode() FileMode // 文件模式位 ModTime() time.Time // 文件修改时间 IsDir() bool // 等价于Mode().IsDir() Sys() interface{} // 底层数据来源(可以返回nil) }
其中 Name()
返回的只是文件名,并没有文件所在的路径,所以当遍历一个目录下所有的文件时就不能准确知道文件所在的路径。所以要在每读取到一个文件时,记录下文件的路径,因此可以定义一个结构体,记录文件的路径和文件信息,完整代码如下:
package main import ( "fmt" "io/ioutil" "os" "path" "strings" ) type fileList struct { path string fileInfo os.FileInfo } func main(){ dir := "D:/go-project/src/" dirList, err := readDir(dir); if err != nil { fmt.Println("readdir error:", err) return } for k, v := range dirList { fmt.Println(k, v.path + v.fileInfo.Name()) } } //递归遍历目录下所有文件 func readDir(dir string) (data []fileList, err error) { //判断文件或目录是否存在 file, err := os.Stat(dir) if err != nil { return data, err } //如果不是目录,直接返回文件信息 if !file.IsDir() { data = append(data, fileList{path.Dir(dir) + "/", file}) return data, err } fileInfo, err := ioutil.ReadDir(dir) if err != nil { fmt.Println(fileInfo) return data, err } //目录为空 if len(fileInfo) == 0 { return } for _, v := range fileInfo { if v.IsDir() { if subDir, err := readDir(dir + v.Name()); err != nil { return data, err } else { data = append(data, subDir...) } } else { data = append(data, fileList{strings.TrimRight(dir, "/") + "/", v}) } } return data, err }