os.stat 返回的 size() 就是文件逻辑字节大小,即磁盘上该文件实际占用的字节总数,int64 类型,非块大小、非压缩后体积;调用后必须检查 err,否则可能 panic。

os.Stat 返回的 Size() 就是文件字节大小
别绕弯子,os.Stat 获取的 os.FileInfo 对象里,Size() 方法直接返回 int64 类型的字节数——它就是你想要的“文件大小”,不是块大小、不是逻辑长度、不是压缩后体积,就是磁盘上该文件实际占用的字节总数。
常见错误是拿到 os.FileInfo 后去读取 Mode() 或误以为要自己调用 os.ReadFile 再算 len(),纯属多此一举,还可能因读取失败或内存溢出崩掉。
-
os.Stat不打开文件,只查元数据,快且安全 - 对符号链接默认解析目标文件(即返回目标文件大小),如需链接自身信息,用
os.Lstat - 若路径不存在或权限不足,
os.Stat返回非 nil 错误,必须检查,否则Size()调用会 panic
正确调用 os.Stat 并安全取 Size()
核心就三步:调用 → 检错 → 取值。没别的花样。
示例:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
fi, err := os.Stat("/path/to/file.txt")
if err != nil {
log.Fatal(err) // 或按需处理:文件不存在、permission denied 等
}
size := fi.Size() // int64,单位字节
- 不要忽略
err:常见错误包括no such file or directory、permission denied,不检查会导致后续 panic -
Size()返回的是int64,直接用于计算或日志没问题;转成 KB/MB 时注意整除和浮点精度(比如float64(size) / 1024) - Windows 下路径分隔符用
/或\都行,Go 的os.Stat全平台兼容
和 os.File 的 Stat() 方法有啥区别?
两者返回的 os.FileInfo 完全一致,Size() 行为毫无差别。区别只在调用时机和资源开销。
- 用
os.Stat(string):只查路径,不打开文件,轻量,适合“只看大小不读内容”的场景 - 用已打开的
*os.File调file.Stat():已持有句柄,再查一次元数据,略冗余;但如果你本就要读文件,顺手调一下也无妨 - 注意:
file.Stat()不会因文件被外部修改而失效,它查的是当前内核缓存的 stat 结果,和os.Stat语义一致
为什么有时候 Size() 和 du -b 不一样?
基本不会不一样——只要 du -b 查的是同一个文件(且没加 --apparent-size),结果应该完全一致。
如果差了,大概率是踩了这几个坑:
- 路径指向的是符号链接,
os.Stat解析了目标,而你手动du时没加-L,导致比对对象不同 - 用了
os.Lstat却误以为它返回链接目标的大小(其实返回的是链接文件自身的大小,通常几十字节) - 文件是稀疏文件(sparse file),
du -h默认按实际磁盘占用显示,但du -b和Size()都报告逻辑大小(即 lseek 最大偏移 + 1),这才是标准定义 - 文件系统挂载时启用了压缩(如 ZFS、Btrfs),
Size()仍返回逻辑大小,而du显示物理占用 —— 这属于正常行为差异,不是 bug
真正要小心的,是混淆“逻辑大小”和“磁盘占用”。Golang 的 Size() 始终是逻辑大小,这也是绝大多数场景需要的值。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










