在Go语言中,获取文件或文件夹的详细信息是文件系统操作的基础任务之一。通过使用标准库osio/fs,你可以轻松地访问文件的元数据,如大小、修改时间、权限等。

使用os.Stat获取文件信息

os.Stat函数返回一个FileInfo接口,它提供了文件或文件夹的基本信息。下面的示例展示了如何获取一个文件的详细信息。

package main

import (
    "fmt"
    "os"
)

func main() {
    info, err := os.Stat("example.txt")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Name:", info.Name())
    fmt.Println("Size:", info.Size(), "bytes")
    fmt.Println("Mode:", info.Mode())
    fmt.Println("ModTime:", info.ModTime())
    fmt.Println("IsDir:", info.IsDir())
}

提示:如果文件不存在,os.Stat会返回一个错误,因此务必检查错误处理。

FileInfo接口的方法

FileInfo接口定义了多个方法来获取文件属性。下表列出了常用的方法及其描述。

方法 描述 示例输出
Name() 返回文件或文件夹的名称 example.txt
Size() 返回文件大小(字节) 1024
Mode() 返回文件权限模式 -rw-r--r--
ModTime() 返回最后修改时间 2023-10-01 12:00:00
IsDir() 返回是否为文件夹 false

遍历文件夹内容

要获取文件夹中所有文件的详细信息,可以使用os.ReadDirfilepath.Walk。下面的示例使用os.ReadDir来列出文件夹中的条目。

package main

import (
    "fmt"
    "os"
)

func main() {
    entries, err := os.ReadDir(".")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    for _, entry := range entries {
        info, err := entry.Info()
        if err != nil {
            fmt.Println("Error getting info for", entry.Name(), ":", err)
            continue
        }
        fmt.Printf("Name: %s, Size: %d bytes, IsDir: %v\n", info.Name(), info.Size(), info.IsDir())
    }
}

注意os.ReadDir在Go 1.16中引入,它比ioutil.ReadDir更高效,推荐使用。

使用filepath.Walk递归遍历

对于需要递归遍历整个目录树的情况,filepath.Walk是一个强大的工具。下面的示例展示了如何遍历文件夹并打印每个文件的路径和大小。

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func main() {
    err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        fmt.Printf("Path: %s, Size: %d bytes\n", path, info.Size())
        return nil
    })
    if err != nil {
        fmt.Println("Error:", err)
    }
}

获取符号链接信息

如果文件是符号链接,os.Stat会返回链接指向的目标文件信息。要获取链接本身的信息,可以使用os.Lstat。下面的示例演示了这一点。

package main

import (
    "fmt"
    "os"
)

func main() {
    // 假设有一个符号链接 link.txt 指向 example.txt
    info, err := os.Lstat("link.txt")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Is symbolic link:", info.Mode() & os.ModeSymlink != 0)
    fmt.Println("Link info:", info)
}