辨析:硬链接与符号链接

前言

        我们都知道,在 Linux 文件系统中,每个文件都仅会占用一个 inode,文件的实际内容由 inode 的记录来指向。若想要读取该文件,则必须经过目录记录的文件名来找到对应的 inode 节点号。也就是说,文件名只与目录有关,而 inode 却与文件内容有关。所以可以认为,inode 才是文件的唯一标识而非文件名

一、硬链接(Hard Link)

        前面我们提到,每个文件仅占用一个 inode ,那么一个 inode 是否同样也只能被一个文件占用,还是说可以被多个文件占用?答案是后者,这也是硬链接的由来。
        所谓的硬链接指的就是,在某个目录下新增一条文件名链接到某个 inode 号码的关联记录,简单来说,就是对一个文件取了别名。若不太理解,没关系,我们可以通过下面的示例来具体说明。
        假如在我的系统中,Test 目录下有一个 test.txt 文件,其相关信息以及内容如下:

        此时,若对它建立一个硬链接,如下:

        通过上面所显示的信息,我们可以发现:

  • test.txthard.txt 两个文件都链接到 3707334 这个 inode 号码;
  • 这两个文件除了文件名之外,其他的所有相关信息都一模一样;
  • 在显示的第二个字段中,原本的数据 1 变成了 2,这个字段被称为链接,即有多少个文件名链接到这个 inode 号码。

        对上面的例子来说,虽然两个文件名不同,但是不管使用哪个文件名均可以从同一个数据块中读取出相同的数据。而这正是硬链接的好处所在,即安全共享。就是说,我们将任何一个文件删除,其实 inode 和区块都还是存在的,只是将文件的链接数减一而已,此时仍然可以通过另一个文件名来读取到正确的数据。而只有当链接数减到0时,该文件才会从文件系统中彻底删除。此外,不论我们使用哪一个文件名来编辑,最终的结果都会写入到相同的 inode 与区块中,因此均能进行数据的修改。
        一般来说,使用硬链接设置链接文件时,磁盘的空间与 inode 的数量都不会改变。其本质实际上就是在某个目录下的区块多写入一个关联数据而已,这既不会增加 inode 也不会消耗区块数量。
        介绍到这里,我们对硬链接应该有了基本认识。接下来,我们再来谈谈硬链接的一些限制,如下:

  • 不能跨文件系统
  • 不能链接目录

        对第一条限制我们能够很好地去理解,因为一个文件的 inode 号码是相对于整个文件系统来说的,它是这个文件在当前系统分区中的索引值。若是跨越了文件系统,那么这些链接的 inode 就不是同一个,更不用说数据区块了,所以硬链接是不可能跨越文件系统的。
        但对于第二条限制,这又是怎么回事呢?
        这是因为如果使用硬链接到目录时,链接的数据需要连同被链接目录下面的所有数据都建立链接。举例来说,如果你要将 /Test 使用硬链接建立一个 /Hard 的目录时,那么在 /Hard 下面的所有文件名同时都与 /Test 下面的文件名要建立硬链接,而不是仅链接到 /Hard/Test 而已。并且,未来如果需要在 /Hard 下面建立新文件时,连带 /Test 下面的数据又要建立一次硬链接,因此造成相当大的环境复杂度。所以,目前硬链接对于目录暂时还是不支持的。
        最后,我们再来探讨一个问题,当我们新建一个目录时,它默认的链接数量会是多少?
        首先,让我们想想一个空目录里面至少会存在什么?其实就是存在 ... 这两个目录。假如我现在新建一个目录 ~/Class/Test,那么基本上会有三个东西,那就是:

  • ~/Class/Test
  • ~/Class/Test/.
  • ~/Class/Test/..

        其中 ~/Class/Test~/Class/Test/. 其实是一样的,都代表该目录,而 ~/Class/Test/.. 代表的是该目录的上级目录 ~/Class。所以说,当我们新建一个目录时,新目录的链接数是2,而上级目录的链接数则会增加1。示例如下:

在这里插入图片描述

二、符号链接(Symbolic Link)

        符号链接又被称为软链接,它可以理解为我们常见的快捷方式。其实质上就是建立一个独立的文件,而这个文件会让数据的读取指向它链接的那个文件的文件名。同样,我们通过下面的示例来具体说明。
        假如在我的系统中,Test 目录下有一个 test.txt 文件,其相关信息以及内容如下:

在这里插入图片描述
        此时,若对它建立一个符号链接,如下:

在这里插入图片描述
        通过上面所显示的信息,我们可以发现:

  • test.txtsymbolic.txt 两个文件指向不同的 inode 号码,说明这是两个独立的文件,也说明由符号链接所建立的文件会占用新的 inode 与区块,这一点和硬链接是完全不同的
  • 在第一个字段中,symbolic.txt 的文件类型为 l,即代表这是个链接文件
  • 在第五个字段中,symbolic.txt 的文件大小为 8B,这是因为其箭头后面的文件名 test.txt 共有8个字母,而每个字母占用1个字节,所以文件大小就是 8B 了。这说明链接文件的内容就是目标文件的文件名

        此外,我们还注意到 symbolic.txt 这个链接文件读取到的数据和 test.txt 是一样的,这该如何理解呢?
        其实,在系统内部首先通过 symbolic.txt 这个文件名找到其 inode 号码 3707332,接着再通过这个 inode 号读取到链接文件的内容,此时读取到的仅有目标文件的文件名 test.txt ,然后在通过这个目标文件的文件名找到其 inode 号码 3707329,最后通过这个 inode 号就可以读取到正确的数据了。其大致流程如下图所示:

symbolic.txt
3707332
test.txt
3707329
实际数据

        所以也可以看出,当我们对链接文件进行修改时,则修改的其实是目标文件,不论这个目标文件被链接到哪里去,只要修改了链接文件,目标文件就跟着改变。这一点,和硬链接是类似的。
        到这里,我们再想想一个问题,倘若我现在将目标文件 test.txt 删除掉,那么链接文件 symbolic.txt 还能读取到数据吗?

在这里插入图片描述
        通过上面所显示的信息,我们可以发现,若将目标文件删除,那么链接文件就无法读取到数据,即链接失效了。但若此时我们又重新添加一个目标文件 test.txt,还会如此吗?

在这里插入图片描述
        从上面显示信息来看,当重新添加了目标文件后,链接恢复有效,通过链接文件又可以读取到正确的数据了。
        通过上面的示例来看,似乎硬链接比较安全,因为即使某一个目录下的关联数据被删除,也没有关系,只要有任何一个目录下存在着关联数据,那么该文件就不会不见。
        不过由于硬链接的限制太多,包括无法链接目录等,所以在用途上面是比较受限的,反而是符号链接的使用范围更广。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值