youyichannel

志于道,据于德,依于仁,游于艺!

0%

HardLink VS SymbolicLink

有时候我们希望给某个文件取别名,那么在 Linux 中可以通过硬链接 (Hard Link)软链接 (Symbolic Link) 的方式来实现,它们都是比较特殊的文件,实现方式是不相同的。

索引节点 (index node)

Linux 中,最经典的一句话 「一切皆文件」,不仅是普通的文件和目录,就连块设备、管道、socket 等,也都是统一交给文件系统管理的。

Linux 文件系统会为每个文件分配两个数据结构:索引节点 (index node) 和目录项 (directory entry),它们主要用来记录文件的元信息和目录层次结构。

  • 索引节点 (inode),用来记录文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。索引节点是文件的唯一标识,它们之间一一对应,也同时都会被存储在硬盘中,所以索引节点同样占用磁盘空间
  • 目录项 (dentry),用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是,目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存

由于索引节点唯一标识一个文件,而目录项记录着文件的名字,所以目录项和索引节点的关系是多对一,也就是说,一个文件可以有多个别名。比如,硬链接的实现就是多个目录项中的索引节点指向同一个文件。

graph LR;
    目录项 -->|记录文件名| 文件;
    索引节点 -.->|唯一标识| 文件;

📢注意:目录也是文件,也是用索引节点唯一标识,和普通文件不同的是,普通文件在磁盘里面保存的是文件数据,而目录文件在磁盘里面保存子目录或文件。

目录项和目录是一个东西吗?

并不是一个东西。目录是一个文件,持久化存储在磁盘;目录项是内核一个数据结构,缓存在内存。

如果查询目录频繁从磁盘读,效率会很低,所以内核会把已经读过的目录用目录项这个数据结构缓存在内存,下次再次读到相同的目录时,只需从内存读就可以,大大提高了文件系统的效率。

📢注意,目录项这个数据结构不只是表示目录,也是可以表示文件的。

硬链接是多个目录项中的「索引节点」指向一个文件,也就是指向同一个 inode,但是 inode 是不可能跨越文件系统的,每个文件系统都有各自的 inode 数据结构和列表,所以硬链接是不可用于跨文件系统的。由于多个目录项都是指向一个 inode,那么只有删除文件的所有硬链接以及源文件时,系统才会彻底删除该文件

软链接相当于重新创建一个文件,每个文件有独立的 inode,但是这个文件的内容是另外一个文件的路径,所以访问软链接时,实际上相当于访问到了另一个文件,所以软链接是可以跨文件系统的,甚至目标文件被删除了,链接文件仍存在,只是指向的文件不存在(查找无果)。