调用stat()填充struct stat后,st_ino为inode编号,st_dev为设备号,二者组合(st_dev, st_ino)才能唯一标识文件;需检查返回值是否为0,路径有效,并区分stat/lstat/fstat用途。

如何用 stat 系统调用读取 inode 元数据
Linux 下 C++ 获取文件 inode 信息,最直接的方式就是调用 stat 系统调用封装的库函数。它不依赖 C++ 标准库,而是通过 提供的 stat()、fstat()、lstat() 三个函数完成——它们本质都是触发内核的 stat 系统调用,只是入参不同。
关键点在于:你拿到的 struct stat 里,st_ino 就是 inode 编号,st_dev 是设备号(用于唯一标识该 inode 所在的文件系统),这两个字段合起来才能全局定位一个 inode。
常见错误是只打印 st_ino 就以为“拿到了 inode”,却忽略了同一 inode 编号可能在不同挂载点重复出现(比如 bind mount 或多个 ext4 分区)。
-
stat("path", &sb):解析路径,遇到符号链接会自动跳转后获取目标 inode -
lstat("path", &sb):不解引用符号链接,返回链接文件自身的 inode(对分析链接结构很重要) -
fstat(fd, &sb):已打开文件描述符时用,避免重复路径查找,性能略优且可绕过权限检查(只要 fd 有效)
st_ino 和 st_dev 为什么必须一起看
单独一个 st_ino 值没有全局唯一性。Linux 中 inode 编号由文件系统自行分配,ext4、XFS、btrfs 都从 1 开始编号;即使同一块磁盘上多个分区,inode 1 也会反复出现。
真正能定位“哪个文件系统上的哪个 inode”的,是二元组:(st_dev, st_ino)。其中 st_dev 是主设备号+次设备号打包的值(可用 major()/minor() 宏拆解),对应 /proc/partitions 或 ls -ld /dev/sda1 的设备节点。
实操建议:
- 做文件去重或硬链接检测时,必须同时比对
st_dev和st_ino,否则跨文件系统误判为同一文件 - 用
stat -c "%d %i" file可快速验证这对值,%d 对应st_dev,%i 对应st_ino - 注意:某些虚拟文件系统(如
proc、sysfs)的st_dev可能为 0 或伪造值,不能假设所有设备号都可映射到真实块设备
硬链接与 st_nlink 字段的实际含义
st_nlink 表示该 inode 当前被多少个目录项(hard link)指向。它不是“有多少个硬链接文件”,而是“还有几个活跃的目录项引用这个 inode”。当最后一个引用被 unlink() 或进程关闭所有 fd 后,内核才真正回收 inode。
根据 package.json 中的 engines 字段自动检测 Node.js 版本需求,未安装 nvm 时自动安装并切换至对应版本。支持 Windows、macOS、Linux。适用于 Node.js 项目开发、版本切换和环境配置。
这个字段常被误读为“硬链接数量”,但要注意:
- 创建硬链接会增加
st_nlink,删除硬链接会减少;但open()不影响它,close()也不影响 - 进程打开文件后
unlink()该路径,st_nlink变为 0,但 inode 仍存在,直到进程 close fd —— 这是“已删除但未释放”文件的底层原理 - 如果看到
st_nlink == 0,说明该 inode 已无路径可达,但可能仍有进程持有 fd(/proc/*/fd/下可见)
为什么不用 getxattr 或 ioctl 读更底层的 inode 内容
标准 stat 调用只暴露内核愿意公开的元数据子集(时间戳、权限、大小、链接数、设备/ino)。它不提供 inode 在磁盘上的物理位置(block number)、扩展属性存储方式、或日志状态等细节。
想进一步挖,有两条路,但都不推荐常规使用:
-
ioctl(fd, EXT2_IOC_GETFLAGS)等文件系统私有 ioctl:仅限 root,接口不稳定,ext4/XFS 实现不同,且需打开文件(不能对路径调用) - 读取原始块设备(如
/dev/sda1)+ 解析文件系统结构:需 root、绕过缓存、手动实现 fs driver 逻辑,极易出错,且现代文件系统(如 btrfs)根本不保证 inode 与磁盘 block 的静态映射
真正需要底层 inode 结构的场景极少,绝大多数监控、备份、去重逻辑,st_dev + st_ino + st_mtime + st_size 四个字段已足够可靠。强行深入只会把代码绑定到特定内核版本或文件系统类型。
硬链接判断、文件变更检测、跨进程文件身份识别——这些日常需求,stat 给的已经够用。别碰磁盘块,也别信“完全底层”这种模糊说法。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










