c++如何实现文件系统的符号链接和硬链接【详解】

浅浩君_7960

浅浩君_7960

2026-04-13

886人浏览

原创

linux/macos下用symlink()和link()创建软硬链接:symlink(目标, 链接名)支持相对/绝对路径且目标可不存在;link(已有文件, 新链接名)要求目标存在、同文件系统、非目录,失败返回-1并设errno。

c++如何实现文件系统的符号链接和硬链接【详解】

Linux/macOS 下用 symlink() 和 link() 创建符号链接与硬链接

在 C++ 中创建链接不靠标准库,而是调用系统 API。Linux 和 macOS 都提供 POSIX 接口:symlink() 做符号链接,link() 做硬链接。Windows 不支持原生 link()(硬链接需管理员权限 + CreateHardLink()),所以跨平台代码要条件编译。

关键点:两个函数都操作路径字符串,不涉及 C++ 流或文件对象;成功返回 0,失败返回 -1 并设置 errno(比如 EEXIST 表示目标已存在,EPERM 表示权限不足)。

  • symlink("target.txt", "link_to_target"):第一个参数是目标路径(可相对/绝对),第二个是链接自身路径
  • link("existing.txt", "hard_link_to_existing"):两个参数都必须是已存在的普通文件的绝对或相对路径;不能跨文件系统
  • 硬链接不能指向目录(Linux 默认禁止,会报 EPERM),符号链接可以
  • 符号链接的目标路径在创建时不校验是否存在;硬链接的目标必须真实存在且是普通文件

Windows 上创建硬链接要用 CreateHardLink(),符号链接需额外权限

Windows 的硬链接和符号链接都是 NTFS 特性,但默认受限。创建硬链接只需调用 CreateHardLink(),但符号链接(CreateSymbolicLink())要求进程启用 SE_CREATE_SYMBOLIC_LINK_PRIVILEGE 权限——普通用户程序默认没有,会失败并返回 ERROR_PRIVILEGE_NOT_HELD。

常见错误现象:CreateSymbolicLink() 返回 0 且 GetLastError() 是 1314,就是权限问题。解决办法要么以管理员身份运行,要么在 manifest 中声明权限(不推荐普通工具这么做)。

  • 硬链接只支持文件,不支持目录;符号链接支持文件和目录(需传 SYMBOLIC_LINK_FLAG_DIRECTORY)
  • CreateHardLink() 第二个参数是新链接路径,第一个是已有文件路径,顺序和 POSIX link() 一致
  • 路径字符串建议用宽字符版本(CreateHardLinkW),避免编码问题;传入路径需为绝对路径或当前驱动器下的有效相对路径
  • 所有 Windows 链接 API 都要求目标文件系统为 NTFS;FAT32/exFAT 不支持

判断一个路径是否为符号链接:用 lstat() 而非 stat()

想确认某个路径是不是符号链接,不能用 stat() —— 它会自动解引用,返回目标文件的属性。必须用 lstat()(POSIX)或 GetFileAttributesEx()(Windows)来读取链接自身的元数据。

C++14
C++14

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

下载

在 Linux/macOS 上:lstat(path, &sb) == 0 && S_ISLNK(sb.st_mode) 才表示它是符号链接;硬链接无法通过元数据区分,因为所有硬链接共享同一个 inode,st_ino 和 st_nlink 字段反映的是文件本身而非“链接实体”。

  • lstat() 对硬链接和普通文件返回结果一致;只有符号链接会被识别出来
  • Windows 下用 GetFileAttributesEx(path, GetFileExInfoStandard, &data),然后检查 data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT
  • 注意:符号链接可能损坏(目标被删),lstat() 仍能成功,但 readlink() 会失败;硬链接只要有一个存在,文件数据就还在

删除链接时的陷阱:硬链接删的是“引用”,符号链接删的是“链接本身”

unlink() 或 std::filesystem::remove() 删除符号链接时,只删链接文件,不影响目标;但删除硬链接,只是减少该文件的链接计数(st_nlink),只有当计数降为 0 且无进程打开它时,系统才真正回收磁盘空间。

这意味着:硬链接不是“副本”,而是同一份数据的多个入口;误删一个硬链接不会丢数据,但误删最后一个硬链接 + 忘记关闭打开句柄,可能导致文件残留(unlinked but open)。

  • 用 stat() 查看 st_nlink 可知还有几个硬链接存在(对普通文件有意义,对符号链接恒为 1)
  • 符号链接可被 readlink() 读出目标路径;硬链接无法反查“谁链接了我”
  • 备份工具、rsync -a 默认保留符号链接(作为链接复制),但通常把硬链接展开成独立文件——除非显式加 --hard-links

硬链接的本质是 inode 引用,符号链接是路径字符串;理解这点,才能避开“为什么删了链接文件,目标还占着空间”或“为什么改了符号链接目标,原来的内容就变了”这类困惑。

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

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1738

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2684

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6064

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

5669

6

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

2024.03.22

7334

16

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2024.04.29

10714

11

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.07.29

5479

17

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.07

5947

13

常用字符串方法大全
常用字符串方法大全

常用字符串方法大全

2025.08.08

3008

14

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习