Linux下用stat()获取inode号最直接:调用stat()填充struct stat,检查返回值为0后读取sb.st_ino;需用绝对路径或有效相对路径,跨文件系统唯一性须结合st_dev判断,符号链接默认解析目标,若需自身inode应改用lstat()。

Linux下用stat()获取inode号最直接
在Linux系统中,stat()是获取文件inode号的标准方式,无需自己解析目录项或调用底层getdents64()。它封装了内核的sys_stat()系统调用,返回结构体struct stat,其中st_ino字段就是你要的inode号。
注意:必须用绝对路径或相对路径访问**已存在**的文件;对符号链接默认返回目标文件的inode(若需链接自身的inode,改用lstat())。
-
stat()成功时返回0,失败返回-1并设置errno(如ENOENT表示文件不存在) - 跨文件系统时,inode号仅在本文件系统内唯一;不同分区的两个文件可能有相同
st_ino - 不要用
fstat()替代——它需要先open()获得fd,而open()本身可能触发重定向或权限检查,引入额外失败路径
struct stat里st_ino的类型和平台差异
st_ino在glibc头文件中定义为ino_t,实际是unsigned long(x86_64上通常是64位),但不能直接用int或long long接收——某些嵌入式平台或旧ABI可能用32位。
安全写法是始终用ino_t声明变量,并用%lu格式化输出(printf("%lu", sb.st_ino)),避免截断或警告。
立即学习“C++免费学习笔记(深入)”;
根据 package.json 中的 engines 字段自动检测 Node.js 版本需求,未安装 nvm 时自动安装并切换至对应版本。支持 Windows、macOS、Linux。适用于 Node.js 项目开发、版本切换和环境配置。
- 在macOS(XNU)上,
st_ino也有效,但语义与Linux一致:同一卷内唯一 - Windows不支持inode概念,
stat()返回的st_ino是模拟值(通常为0或伪随机),不可用于唯一性判断 - 如果程序需跨平台且依赖inode做去重,务必加
#ifdef __linux__保护逻辑
为什么readdir()拿到的d_ino有时是0?
当用readdir()遍历目录时,struct dirent里的d_ino字段理论上也存inode号,但它受文件系统实现限制:某些FS(如ext4在特定挂载选项下、XFS、Btrfs)可能不缓存或不暴露该值,此时d_ino返回0。
这不是bug,而是POSIX允许的行为。glibc文档明确说明:d_ino“may be 0 if the filesystem does not support it”。所以不能依赖它做可靠判断。
- 要确保拿到真实inode,必须对每个
d_name调用stat()(拼出完整路径后) - 批量处理时注意性能:大量
stat()会触发多次磁盘I/O;可考虑openat(AT_FDCWD, path, O_NOFOLLOW | O_PATH)+fstat()减少路径解析开销(需Linux 2.6.39+) -
getdents64()系统调用虽能绕过glibc,但返回结构体仍含d_ino,同样可能为0——没解决根本问题
硬链接场景下st_ino的含义和陷阱
多个硬链接指向同一inode,stat()对任意一个路径调用都会返回相同的st_ino值。这是正确行为,也是判断是否为同一文件的依据(配合st_dev判断同设备)。
但要注意:st_nlink字段只反映当前路径所在目录项的链接计数,不是全局引用数;且删除一个硬链接后,其他路径的st_ino不变,直到所有链接被删且无进程打开该inode。
- 比较两个路径是否指向同一文件,应同时比对
st_dev和st_ino,缺一不可(不同设备可能有相同inode号) - 不要用
st_ino做持久化ID:文件被rename()或mv到另一文件系统后,inode必然变化 - 备份工具或去重逻辑中,若仅靠
st_ino跳过“重复”文件,可能漏掉跨设备的真正重复内容——此时得靠hash
stat()调用本身很简单,但真正难的是理解inode在不同上下文中的边界:它不是全局唯一ID,不跨设备有效,不随路径迁移,也不保证readdir()一定提供。这些细节一旦忽略,调试时就会卡在“为什么两个明明一样的文件inode却不同”或者“为什么d_ino总是0”这种问题上。

















