相信大家已经或多或少的听过硬链接、符号链接这几个名词了,那硬链接、符号链接到底是什么❓,下面我们将一一揭开这神秘的面纱💃
一、📕前置知识
在进入正题之前,先让我们先来复习下令人头疼🤦的操作系统
1. 磁盘与文件系统
- 磁盘上的数据是以块(block) 为单位存储的,比如每块大小 4KB。
- 文件系统(例如 ext4、NTFS、APFS) 负责组织、管理这些块,确保能找到、读写数据。
2. 什么是 inode(索引节点)
- inode 是文件系统中非常核心的数据结构。
- 每一个文件都有一个独立的 inode(索引节点)。
- inode 里面保存的是文件的元数据,包括:
- 文件大小(多少字节)
- 文件的权限(读/写/执行权限)
- 文件的所有者(user / group)
- 文件的创建、修改、访问时间(ctime/mtime/atime)
- 重要:文件数据在哪些磁盘块上存储(即数据块指针)
- 注意:inode 不存储文件名!
因此可以把inode想象成一张表,表中记录着关于文件的信息,参考下图
相信以大家的水平到这里已经充分的掌握了什么是inode,什么是文件系统,那下面我们便来看一下文件背后是怎么工作的
首先我们要搞清楚的一件事是,目录(/home)也是一种文件,每一个目录也对应一个inode,但是目录inode指向的磁盘存储的是目录中的是“文件名 ➔ inode编号”的列表
比如 /home 这个目录可能存着:
| 文件名 | inode编号 |
|---|---|
| user1.txt | 12345 |
| user2.txt | 12346 |
当你试图访问/home/user1.txt时,系统的做法是这样的:
1.打开home目录内容
2.找到user1.txt对应的
inode3.根据 inode
12345获取文件的元信息,找到数据块指针,读数据。
抽象派化作如下
到这里就可以进入我们的主题硬链接、符号链接,是的你没听错,主题才刚刚开始
二、👻 “文件分身”——硬链接(hardLink)
让我们先来看看百度百科对硬连接的解释:
硬连接是对于
同一文件系统的一个文件的连接,节点是文件存在的唯一标识,在文件系统中是唯一的,但是在不同的文件系统则有可能重复。
看到这里估计大家也是一脸懵逼,用大白话给大家解释其实就是:
每一个真实的文件的文件内容都会存到一个文件系统的磁盘块中,而这个文件的所有信息都会被记录到一个inode中,而硬连接则是通过一个指针指向这个文件的inode,也就是说我们访问一个文件时(如果这个文件是通过硬连接创建的)实际上是去根据这个inode去找到的这个文件,而一个inode可能会被创建多个硬连接,但是实际只有一个文件占用着磁盘空间。
抽象派画作如下
要注意的一个点是
inode上有一个count(图中紫色圈)会记录着当前硬连接的文件数量
因此总结硬连接特点如下:
- 共享数据:多个“文件”通过硬连接指向同一个内容,如果其中一个“文件”改变了这个内容,那么所有的“文件”的内容都会改变
- 文件名和数据分离:无论删除哪个“文件“,只要其他硬连接仍然存在,数据就不会丢失。只有当
count = 0时,该数据才会删除 - 不可跨文件系统:硬连接只能在同一文件系统内创建,因为硬连接指向
inode,而inode只在当前文件系统时唯一的。 - 无法连接目录:通常,用户不能为目录创建硬连接(除非是超级用户),这避免了文件系统结构的混乱。
🧪读到这应该对硬连接有了初步的认识,那趁热打铁我们在终端中实验一下:
1.创建源文件
echo "Hello pnpm" > original.txt
这会在当前目录生成一个名为 original.txt 的文件,内容为 Hello pnpm
2.创建硬链接
ln original.txt hardlink.txt
ln 默认创建硬链接,此时 hardlink.txt 与 original.txt 指向相同 inode,彼此对等
3.查看 inode
ls -i original.txt hardlink.txt
输出类似:
19663043 original.txt
19663043 hardlink.txt
可以看到两者 inode 相同,说明它们引用的是同一物理存储
4.修改内容对等生效
echo "Updated" >> hardlink.txt
cat original.txt
你会在 original.txt 末尾看到 Updated,证明对任一链接的修改都会反映到同一份数据上
5.删除原名不丢数据
rm original.txt
cat hardlink.txt
尽管删除了 original.txt,但 hardlink.txt 依然可读,只有当所有硬链接都被删除后,数据才真正释放
好了相信到这里,大家对硬连接已经有很清晰的认识了,其实也没那么难不是嘛🧐
那接下来让我们继续看看符号连接到底是怎么个事
三、🔗“快捷方式”——符号链接(symLink)
老套路让我们先看看百度百科的解释:
符号链接(软链接)是一类特殊的
文件,其包含有一条以绝对路径或者相对路径的形式指向其它文件或者目录的引用。一个符号链接文件
仅包含有一个文本字符串,其被操作系统解释为一条指向另一个文件或者目录的路径。它是一个独立文件,其存在并不依赖于目标文件。如果删除一个符号链接,它指向的目标文件不受影响。如果目标文件被移动、重命名或者删除,任何指向它的符号链接仍然存在,但是它们将会指向一个不复存在的文件。这种情况被有时被称为被遗弃。
其实对于符号连接来说百度百科的解释还是蛮清晰的,这里我总结几点并配合灵魂绘图,相信你很快就能理解:
-
快捷方式:其实符号连接你就可以理解为
快捷方式 -
存储路径字符串:符号连接并非指向文件本身,而是记录所链接文件的“路径”(字符串),访问符号连接,会根据该路径去找目标文件
-
权限和大小独立:每个软连接都有一个自己的
inode,可以理解为inode存储了目标文件的路径 -
可以跨文件系统:因为软链接存储的是路径信息,所以它可以跨越不同的分区或挂载点。
-
可以链接目录:与硬连接不同,软连接可以方便地链接整个目录。
-
目标删除后,链接会失效(变成“悬挂链接”):如果目标文件被删除或移动,软连接仍然存在,但会指向一个无效的路径,形成“死链接”或“悬挂链接”。
🧪同样的读到这应该对符号连接有了初步的认识,那趁热打铁我们在终端中实验一下:
1.创建源文件
echo "World pnpm" > target.txt
新建 target.txt 并写入内容
2.创建符号链接
ln -s target.txt symlink.txt
-s 表示软链接,生成一个独立 inode 的文件 symlink.txt,其内容为文本 target.txt
3.查看链接信息
ls -l symlink.txt
输出类似:
lrwxrwxrwx 1 user group 10 Apr 27 10:00 symlink.txt -> target.txt
l 开头表示符号链接,箭头后是它所指向的路径
4.访问与删除影响
cat symlink.txt # 正常显示内容
rm target.txt
cat symlink.txt # 会报错“No such file or directory”
删除目标后,symlink.txt 变成“悬挂链接”(broken link),因它只存储路径文本而非数据
5.跨目录/跨分区链接
ln -s /etc etc_link
cd etc_link
pwd # /path/to/project/etc_link
符号链接可指向目录或其他挂载点,类似 Windows 快捷方式
最后总结一下二者的异同
| 特性 | 软链接(Symbolic Link) | 硬链接(Hard Link) |
|---|---|---|
| 指向方式 | 指向目标文件的路径(文件名) | 直接指向目标文件的 inode(数据块) |
| 是否共享 inode | 否,拥有自己的 inode | 是,多个硬链接共享同一个 inode |
| 是否可跨文件系统 | 是,支持跨文件系统 | 否,必须在同一文件系统内 |
| 是否可链接目录 | 是,通常用于链接目录 | 否,通常不允许链接目录(为防止循环引用) |
| 目标文件删除影响 | 目标文件删除后,链接失效(称为“悬挂”或“断链”) | 目标文件删除后,链接仍然有效,文件内容不受影响 |
| 占用磁盘空间 | 占用少量空间(仅存储路径信息) | 不额外占用空间(共享原文件数据) |
| 权限和属性 | 与目标文件独立 | 与目标文件完全相同 |
| 创建命令示例 | ln -s 源文件 链接名 | ln 源文件 链接名 |
| 使用场景 | 常用于快捷方式、跨文件系统链接、链接目录等 | 常用于需要多个路径访问同一文件内容,且不希望目标文件删除后链接失效的场景 |
文章最后再总结下硬链接和符号链接在我们前端中的实际应用场景
-
本地快速发包联调:
npm link/pnpm link可以将本地包实时映射到项目中,继而可以在项目中直接引用改包,免去了反复发布带来的繁琐 -
Monorepo与共享代码:在
pnpm多包仓库中,使用符号链接将共享包引入各个子项目,无需重复安装,同时避免幽灵依赖(yarn、npm@3 的问题),硬链接在同一文件系统中提供多入口(多份文件)而不额外占用空间 -
构建工具与模块解析:webpack、Ts 在遇到符号链接时默认会解析到真实路径等等
.......
这些内容我都会再接下来的文章中一一讲解到,希望大家到时候可以多多关注