linux/macos 下用 stat() 可一次性获取 inode 号(st_ino)和推荐 i/o 块大小(st_blksize),windows 不支持;st_ino 在 ext4/xfs/zfs 等有效但 nfs 下不可跨主机比较,st_blksize 是优化提示而非物理块大小,使用前必须检查 stat() 返回值是否成功。

Linux/macOS 下用 stat() 一次拿到 inode 号和块大小,Windows 不支持 —— 别白费劲去兼容。
用 stat() 读取 st_ino 和 st_blksize
POSIX 标准里,stat() 是唯一可靠入口。它把文件元数据全塞进 struct stat,其中 st_ino 就是 inode 号,st_blksize 是“推荐的 I/O 块大小”(不是磁盘物理块,别混淆)。
实操要点:
-
st_ino在 ext4/xfs/zfs 等主流文件系统上稳定有效;但 NFS 挂载时可能被服务器重映射,不可跨主机比较 -
st_blksize是优化提示,glibc 的fread()会参考它做缓冲,但不强制——你用 1 字节read()也完全合法 - 必须检查返回值:
stat()失败时st_ino和st_blksize内容未定义,直接读会触发未定义行为 - 路径传
const char*,不支持 wide string;想处理 Unicode 路径得先转 UTF-8(Linux)或用stat64()+openat()组合(macOS)
#include <sys>
#include <stdio.h><p>struct stat sb;
if (stat("/path/to/file", &sb) == 0) {
printf("inode: %lu\n", (unsigned long)sb.st_ino);
printf("block size: %ld\n", (long)sb.st_blksize);
} else {
perror("stat failed");
}
</p></stdio.h></sys>
stat() vs fstat():选哪个取决于你手上有啥
两者返回字段完全一致,区别只在输入参数:
- 有路径字符串 → 用
stat() - 已有打开的
int fd(比如刚open()完)→ 用fstat(),避免再走路径解析,略快且线程安全(路径不会被其他线程改) - 如果 fd 来自
/proc/self/fd/这类伪路径,fstat()仍能正常返回真实 inode;而对这些路径调stat()可能返回 0 或失败
注意:fstatat() 在需要遍历目录又想省 chdir() 时有用,但日常几乎用不到。
ZenHeart zenlink 与 zenlink-mcp 为 OpenClaw,涵盖安装、MCP 注册、钩子接线、入站轮询及升级维护。
常见错误:误把 st_blocks 当块大小
st_blocks 是文件实际占用的 512 字节块数(POSIX 强制单位),不是块大小。它和 st_blksize 完全无关:
-
st_blksize = 4096表示“建议按 4K 读写”,和磁盘分配无关 -
st_blocks = 8表示“占了 8 × 512 = 4096 字节磁盘空间”,但空洞文件(sparse file)下这个值可能远小于st_size / st_blksize - 有人用
st_blocks * 512估算磁盘用量,可行;但拿它当 I/O 缓冲尺寸,性能反而下降
MacOS 上 st_blocks 单位也是 512 字节,和 Linux 一致;但某些旧 BSD 变种可能不同,不过现在基本不用管。
Windows 下没戏,别硬套 POSIX
Windows NTFS 没有 inode 概念,GetFileInformationByHandle() 返回的 dwVolumeSerialNumber + nFileIndexLow/High 组合只是内部标识,不满足 inode 语义(比如硬链接共享同一 inode,而 Windows 的硬链接靠 reparse point 实现,索引值不统一)。
如果你在写跨平台代码:
- 明确标注 “Linux/macOS only” 或加
#ifdef __linux__守卫 - 不要试图用
st_ino做跨平台唯一 ID;改用st_dev+st_ino组合,但 Windows 下st_ino总是 0 - 块大小相关逻辑,在 Windows 上可 fallback 到
GetDiskFreeSpace()查扇区大小,但这和 POSIX 的st_blksize完全不是一回事
真正麻烦的是容器环境:Docker 默认用 overlay2,stat() 返回的是 upper layer 的 inode,宿主机上看不到对应文件;k8s Pod 里看到的 inode 和节点上 ls -i 出来的通常对不上——这点调试时特别容易踩坑。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










