一、建立一个文件a.txt

mkdir stat && cd stat && touch a.txt && touch stat_test.go

二、使用 os.Stat() 获取 file 文件信息

打开 stat_test.go 输入:

package stat

import (
    "os"
    "testing"
)

func TestStat(t *testing.T) {
    fileInfo, err := os.Stat("a.txt")
    if err != nil {
        t.Error(err)
    }
    t.Log(fileInfo.Name())    //文件名称
    t.Log(fileInfo.Size())    //文件的大小
    t.Log(fileInfo.Mode())    //fileMode
    t.Log(fileInfo.ModTime()) //修改时间
    t.Log(fileInfo.IsDir())   //是否是目录
}

输出:

a.txt
0
-rw-r--r--
2022-08-16 15:23:46.956139863 +0800 CST
false

三、os.Stat()源码分析

在源码src/os/stat.go我们可以看到

// Stat 返回 一个描述这个文件的  FileInfo 接口 .
// If there is an error, it will be of type *PathError.
func Stat(name string) (FileInfo, error) {
    testlog.Stat(name)
    return statNolog(name)
}

我们在看一下 FileInfo 接口

// A FileInfo describes a file and is returned by Stat and Lstat.
type FileInfo interface {
    Name() string       // 文件名称
    Size() int64        // 文件的字节长度
    Mode() FileMode     // file mode bits
    ModTime() time.Time // 修改时间
    IsDir() bool        // 是否是一个目录
    Sys() interface{}   // underlying data source (can return nil)
}

我们在看一下 FileMode 数据结构

// A FileMode 展示一个文件的  mode(模式) and permission(权限) bits.
type FileMode uint32

四、FileInfo的不同操作系统实现

我是mac系统,在源码src/os/types_unix.go我们可以看到

// A fileStat is 实现 of FileInfo returned by Stat and Lstat.
type fileStat struct {
    name    string
    size    int64
    mode    FileMode
    modTime time.Time
    sys     syscall.Stat_t
}

func (fs *fileStat) Size() int64        { return fs.size }
func (fs *fileStat) Mode() FileMode     { return fs.mode }
func (fs *fileStat) ModTime() time.Time { return fs.modTime }
func (fs *fileStat) Sys() interface{}   { return &fs.sys }

func sameFile(fs1, fs2 *fileStat) bool {
    return fs1.sys.Dev == fs2.sys.Dev && fs1.sys.Ino == fs2.sys.Ino
}

谢谢您的观看,欢迎关注我的公众号。

image.png


海生
104 声望32 粉丝

与黑夜里,追求那一抹萤火。