硬链接与符号链接的介绍与使用 Blog By LTrump

介绍

硬链接是什么?

一个文件有几个文件名(用ln命令实现多个文件名),我们就说该文件的链接数为几。由定义可知,此链接数可以是1,这表明该文件只有一个文件名。

总之,硬链接就是让多个不在或者同在一个目录下的文件名,同时能够修改同一个文件,其中一个修改后,所有与其有硬链接的文件都一起修改了。

——百度百科

硬链接可以简单理解为一个文件只占用一次空间大小的多份拷贝,当然硬链接出来的文件在文件属性、文件内容等方面都是始终一致的

符号链接是什么?

符号链接(软链接)是一类特殊的文件, 其包含有一条以绝对路径或者相对路径的形式指向其它文件或者目录的引用。 符号链接最早在4.2BSD版本中出现(1983年)。今天POSIX操作系统标准、大多数类Unix系统、Windows Vista、Windows 7都支持符号链接。Windows 2000与Windows XP在某种程度上也支持符号链接。

符号链接的操作是透明的:对符号链接文件进行读写的程序会表现得直接对目标文件进行操作。某些需要特别处理符号链接的程序(如备份程序)可能会识别并直接对其进行操作。

一个符号链接文件仅包含有一个文本字符串,其被操作系统解释为一条指向另一个文件或者目录的路径。它是一个独立文件,其存在并不依赖于目标文件。如果删除一个符号链接,它指向的目标文件不受影响。如果目标文件被移动、重命名或者删除,任何指向它的符号链接仍然存在,但是它们将会指向一个不复存在的文件。这种情况被有时被称为被遗弃。

——百度百科

相对于硬链接来说,符号链接其实更像快捷方式,一种功能更为完备的快捷方式,无非快捷方式是需要程序进行识别读取,但对符号链接的操作时文件系统会自行处理。但如果在需要的条件下,符号链接也是可以被识别的。

硬链接/符号链接和快捷方式有什么不同?

快捷方式实际上是一个文件,是一种包含指向文件位置信息的一种文件格式,当所指向的文件被删除或者由于其他原因导致所指向的文件位置不存在时,就会这样:

Snipaste_2020-03-11_17-31-13.png

而快捷方式在Windows中以.lnk结尾,其本身只是作为一个文件存在的,就和.txt、.doc等一样,哪怕所指向的是一个目录,其本身也是一个文件,如果对此感到困惑可以做如下尝试:

  • 首先在D盘下创建一个名为test的目录,并在目录中存放一些文件如test.txt,然后右键创建其快捷方式命名为testlink

  • 随后尝试在资源管理器地址栏中输入:D:\testlink\test.txt,就会出现下图提示

    Snipaste_2020-03-11_17-37-35.png

  • 直接访问D:\test\test.txt则是正常的

对于符号链接,同样是刚刚的D:\test文件夹,大家可以在cmd中运行命令创建符号链接:

mklink -d D:\testlink D:\test

linux下使用ln:

ln -s /mnt/d/test /mnt/d/testlink

由于我使用的是最好的Linux发行版wsl,/mnt/d对应的就是Win下的d盘

然后再以刚刚同样的方式访问:

Snipaste_2020-03-11_17-57-54.png

不仅可以进去,并且地址栏中的地址也没有变化。可见,符号链接本身除非有特殊的需求,否则是不需要程序进行识别的,换言之可以在各种场景当作指向的文件/目录直接使用,而快捷方式只能作为一个lnk文件被读取。

而硬链接也是可以当作被指向的文件直接使用的,但硬链接比符号链接更加彻底,具体区别如下:

硬链接与符号链接有什么不同

以我个人的见解来看,符号链接其实更像一种功能更加完善的快捷方式,其本身还是指向了某个文件位置的,举个最简单的例子,当你把符号链接所指向的文件删除后,依然会报错:

Snipaste_2020-03-11_18-12-07.png

除了能被直接访问以外,它几乎和快捷方式是一模一样的,对符号链接的重命名、移动位置等并不会影响源文件,但移动、删除源文件则会导致符号链接出错。

而硬链接却不同,硬链接拥有和源文件完全对等的关系,可以简单理解为他们都指向了硬盘中的某个位置,所以当硬链接创建完成后,就不再区分谁是源文件,谁是硬链接。当然,无论你修改哪个文件,另一个文件中的内容也会跟着变动,但当你只删除一个文件时,另一个文件依然能够正常访问

用Linux下的视图可以非常清晰地说明这一点:

Snipaste_2020-03-11_18-19-50.png

上图中的符号链接test-symboliclink.txt是能够被识别出来的,并且直接进行vim test-symboliclink.txt的操作也是合法的

而硬链接test-hardlnk.txt则在表面上看起来与源文件一模一样,而当我们进行操作:

  • 修改三者中的任意一个文件,三者的内容会一起更改
  • 删除/重命名/移动test-symboliclink.txt对其余两者不构成影响
  • 删除/重命名/移动test-hardlink.txt对其余两者也无影响,因为符号链接指向的是test.txt
  • 删除/重命名/移动test.txt,对test-hardlink.txt无影响,test-symboliclink.txt无法访问,因为符号链接指向的位置已经不存在了

与此同时,硬链接创建出来的文件,在系统意义上是占用空间的,如一个1GB的文件,创建硬链接后,通过右键查看属性你会发现两个文件大小均为1GB,当然这并不是说这两个文件就占用了2GB的硬盘空间,实际上这两个文件占用的硬盘空间依然只有1GB。于是就会出现一个50GB的硬盘里放了1000个1GB文件的壮观景象:

sp20200311_201451_244.png

硬链接与符号链接的创建

注意事项

  • 原则上讲,硬链接只能针对文件,因为目录只是一种逻辑结构,且目录中的文件并非是在硬盘中连续存储的,当然部分文件系统可能会支持,但是依然不建议使用,因为如果需要目录内容完全一致的话那么使用符号链接就可以了,但这样的话目录内的文件名也是同步的,和我们的目的不符。
  • 硬链接是不能够跨分区使用的,而符号链接可以,因为硬链接直接指向了硬盘中的内容。
  • 当然也不用担心为每个文件一个一个创建硬链接麻烦,会有软件帮你搞定的

一、使用软件(推荐)

如果你建立硬链接不是为了装逼,那么建议你使用这种方法。

软件:HardlinkShellExt

这是64位版本的,如果不适配可以自行上网搜索下载。

下载安装完后剩下的事情就非常简单了

  • 选择你的源文件并右键选择选择源链接点(可以是目录,也可以多选

    Snipaste_2020-03-11_20-42-33.png

  • 随后在你的目标位置(同一分区)下右键-创建为-硬链接/符号链接

    Snipaste_2020-03-11_20-45-46.png

  • 接下来软件的优势就体现出来了,如果你前面选择的是目录的话,创建硬链接时软件会自动按照原来的目录层级创建新的目录并硬链接其中的文件

    • 值得注意的是,这个目录只是仿照源目标创建的目录而已,目录内的内容并不会像符号链接那样同步,目录中的文件名,目录的结构等可以随意更改,也就是说,当你创建完硬链接后,可以直接把里面的文件当成新的副本进行操作。
  • 如果源链接点选择的是目录的话,创建的时候还会有其他的形式可供选择,具体可以查看软件的帮助文档

二、用命令手动创建

如果你真的闲得慌,那么可以用如下命令创建硬链接与符号链接:

Windows

硬链接:mklink /H 目标文件 源文件
符号链接文件:mklink 目标文件 源文件
符号链接目录:mklink /D 目标目录 源目录

记得在管理员权限下运行cmd(powershell好像不行,不知道为什么),另外请尽量使用绝对路径

Linux

硬链接:ln 源文件 目标文件
符号链接:ln -s 源文件/目录 目标文件/目录
尝试对目录进行硬链接操作:ln -d 源目录 目标目录

注意和windows是反着写的哦,同样建议绝对路径

硬链接与符号链接的应用场景

总的来说,硬链接在一个文件需要以两种位置访问时是最佳的解决方案,顺便可以作为备份,而符号链接则通常用于文件与目录的归档,类似于快捷方式,举个例子:

Android之中根目录下有个/sdcard文件夹,这实际就是一个符号链接,在我的手机上指向了/storage/self/primary,然而这也是一个符号链接,指向了真正内部存储存在的位置/storage/emulated/0/

这样就可以保证程序无论是通过什么方式访问内部存储都可以准确到达目的地,而不需要根据手机的文件系统格式进行判断。

而硬链接则可以参考这个案例:

巧妙利用硬链接解决PT下载的资源命名不规范问题