c++怎么在Linux下获取文件的硬链接数_stat结构体st_nlink【附源码】

风晨君_7162

风晨君_7162

2026-03-24

857人浏览

原创

c++oding="utf-8" ?>

必须用 stat() 或其变体(如 lstat())读取 st_nlink 才可靠,因它是唯一可移植获取 inode 硬链接数的方式;readdir() 计数或解析 ls -l 均不可靠。

c++怎么在linux下获取文件的硬链接数_stat结构体st_nlink【附源码】

用 stat() 读取 st_nlink 是唯一可靠方式

Linux 下获取文件硬链接数,必须通过系统调用读取 inode 元数据,stat() 是标准且唯一可移植的途径。lstat() 和 fstat() 也能用,但语义不同:前者不跟随符号链接(推荐用于路径查询),后者需已有文件描述符。直接读取目录项或解析 ls -l 输出不可靠——那只是格式化后的快照,不是真实 inode 状态。

常见错误是误用 readdir() 遍历目录并计数文件名:这算的是目录项数量,不是该 inode 的硬链接数;一个文件可能在多个目录里有硬链接,也可能在同一个目录里有多个同 inode 的硬链接(虽然少见),单纯数名字完全失真。

  • stat("path/to/file", &sb) 成功后,sb.st_nlink 就是当前 inode 的硬链接数
  • 若路径是符号链接,stat() 返回的是它指向的目标的 st_nlink;要查符号链接自身(即 link 文件的 inode 链接数),得用 lstat()
  • st_nlink 类型是 nlink_t,通常是 unsigned long,打印时用 %lu,别用 %d

st_nlink 的值为什么有时和 ls -l 显示不一致

不是 bug,是观察视角不同。比如执行 ls -l /proc/self/fd/ 会看到很多文件显示 st_nlink 为 0 —— 这是内核故意设的,因为 /proc 下的伪文件没有传统 inode 语义,st_nlink 无意义,内核填 0 表示“不适用”。普通磁盘文件不会这样。

另一个典型场景:NFS 或某些 FUSE 文件系统可能不准确报告 st_nlink,尤其在跨服务器硬链接支持不完整时。本地 ext4/xfs 没问题,但一上网络文件系统就得留个心眼。

  • 目录的 st_nlink 至少为 2:自身目录项 + 各子目录里的 ".." 引用;每加一个子目录,st_nlink +1
  • 删除文件时,只有当 st_nlink 降为 0 且无进程打开它,磁盘空间才真正释放
  • 硬链接只能对文件,不能对目录(root 除外),所以目录的 st_nlink 永远不表示“有多少硬链接”,而是“有多少目录项引用这个 inode”

最小可运行示例:检查路径是否被多处硬链接

下面这段代码只做一件事:调用 lstat(),输出 st_nlink,并判断是否大于 1。它避开所有异常处理包装,直击核心逻辑。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
#include <sys>
#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc != 2) return 1;
    struct stat sb;
    if (lstat(argv[1], &sb) == 0) {
        printf("st_nlink = %lu\n", (unsigned long)sb.st_nlink);
        if (sb.st_nlink > 1) {
            printf("→ 该路径对应 inode 至少被硬链接了 %lu 次\n", (unsigned long)sb.st_nlink);
        }
    } else {
        perror("lstat");
    }
    return 0;
}
</stdio.h></sys>

编译:g++ -o linkcnt linkcnt.cpp(C++ 项目里混用 C 头没问题);运行:./linkcnt somefile。注意:必须用 lstat,否则符号链接会被穿透,拿到的是目标文件的链接数,不是你输入的那个路径本身的 inode 链接数。

硬链接数在 C++ 中没法绕过 C API 直接拿

标准 C++20 提供了 std::filesystem::status() 和 symlink_status(),但它们不暴露 st_nlink。GCC libstdc++ 和 Clang libc++ 都没把 nlink 塞进 file_status 或扩展属性里。想在 C++ 里拿到它,终究得调 stat() 或 lstat(),封装成 inline 函数即可,没必要强求“纯 C++”。

容易踩的坑是试图用 std::filesystem::is_regular_file() 一类函数替代元数据读取——它们内部也调 stat,但只提取布尔结果,把 st_nlink 扔掉了。性能上没差别,但信息丢了。

  • 不要为了“用 C++ 标准库”而放弃 lstat();它稳定、精确、零额外开销
  • 如果项目已用 std::filesystem::path,可以 lstat(p.c_str(), &sb),安全又自然
  • st_nlink 是瞬时值:两次调用 stat() 之间,其他进程可能增删硬链接,别缓存它做长期判断

硬链接数本身不难读,难的是理解它到底代表什么——它不是“文件被引用了多少次”的用户级概念,而是内核 inode 结构体里那个整数字段,含义严格绑定于文件系统实现和当前时刻。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

4994

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

5151

25

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

2023.06.21

4290

4

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

2023.06.29

3613

10

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

2023.06.30

2853

5

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

2023.07.05

7030

7

linux系统安装教程
linux系统安装教程

linux系统是一种可以免费使用,自由传播,多用户、多任务、多线程、多CPU的操作系统。本专题提供linux系统安装教程相关的文章,大家可以免费体验。

2023.07.06

6662

7

linux查看文件夹大小
linux查看文件夹大小

Linux是一种自由和开放源码的类Unix操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。linux怎么查看文件夹大小呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.20

3833

8

linux查看ip命令
linux查看ip命令

本专题为大家提供linux查看ip命令相关文章内容,感兴趣的朋友可以免费下载体验试试。

2023.07.20

3325

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习