直接调用 stat() 填充 struct stat,st_ino 字段即 inode 编号,st_dev 字段即设备 ID(主次设备号合成);必须检查 stat() 返回值是否为 0,否则字段未定义,且 st_ino 仅在同文件系统内唯一。
Linux 下 C++ 获取文件 inode 和设备 ID,直接用就行,别碰或除非你明确需要符号链接或已打开的 fd。
怎么用
拿到 inode 和设备 ID
核心就是调用系统函数填一个
,里面两个字段直接可用:
是 inode 编号,
是设备 ID(主+次设备号合成的 dev_t)。注意不是文件系统 UUID,也不是挂载点路径。
常见错误现象:
看起来是 0 或极小值 —— 很可能是路径写错、权限不足导致
失败但没检查返回值;或者传了相对路径但当前工作目录变了。
必须检查
返回值是否为 0,否则
/
未定义
路径要用绝对路径或确保相对路径上下文稳定(比如用
拼接)
是设备标识,相同值意味着同一块物理/虚拟设备(如 /dev/sda1),但不同文件系统可能共享同一
(比如 bind mount)
和
别搞混
是文件所在设备的 ID,所有普通文件、目录都靠它定位存储设备;
只对字符/块设备文件有意义,表示该设备文件“指向”的底层设备号(比如
的
就是 sda 自己的主次号)。
立即学习
“
C++免费学习笔记(深入)
”;
C知道
CSDN推出的一款AI技术问答工具
下载
使用场景:判断两个路径是否在同一个挂载点?比
更可靠的是结合
查
,但日常做硬链接检测、去重、缓存隔离,
组合已经足够唯一。
对普通文件调
后,
值无意义,别读它
用
创建的设备文件,
是它所在磁盘分区的设备号,
才是它模拟的硬件设备号
容器环境里
可能被 namespace 隔离,宿主机看到的值和容器内不一定一致
为什么不用
或
会绕过符号链接本身,读取目标文件的
—— 如果你真想获取符号链接自己的 inode(即链接文件自身的元数据),就得用
;但多数人要的是目标文件的 inode,这时
更直觉。
需要先
,多一次系统调用,还带出 fd 管理负担。除非你 already have the fd(比如从
或
来的),否则纯查元数据没必要走这条路。
符号链接场景下,
返回目标文件的
,
返回链接文件自身的
的
和
对同一文件结果一致,但无法获取路径名相关的信息(比如无法知道这个 fd 是从哪个路径 open 的)
某些 NFS 或 FUSE 文件系统里,
可能比
少一次网络往返,但这是例外,不是默认行为
真正容易被忽略的是:inode 编号只在单个文件系统内唯一,跨设备比较
没意义;而
虽然能区分设备,但在 overlayfs、bind mount、user namespaces 下可能失真 —— 如果你在做分布式缓存或一致性校验,别只依赖这两个字段,加一层逻辑路径哈希或内容摘要更稳妥。
stat()lstat()fstat()stat()struct statst_inost_devst_inostat()stat()st_inost_devgetcwd()st_devst_dev
#include
struct stat sb;
if (stat("/path/to/file", &sb) == 0) {
printf("inode: %lu, device: %lu\n", (unsigned long)sb.st_ino, (unsigned long)sb.st_dev);
}
st_devst_rdevst_devst_rdev/dev/sdast_rdevst_devstatfs()f_fsidst_dev + st_inostat()st_rdevmknodst_devst_rdevst_devlstat()fstat()lstat()st_inolstat()stat()fstat()open()accept()pipe()stat()st_inolstat()st_inofstat()st_inostat()fstat()stat()st_inost_dev