在Linux系统中有两种链接文件,分别为软链接和硬链接。
软链接类似于Windows系统中的快捷方式。
创建软链接和硬链接的命令如下:
软链接: ln -s 源文件 链接文件
硬链接: ln 源文件 链接文件
首先创建一个文件test,分别创建对应的软链接和硬链接
从图中可以看出硬链接和源文件具有相同的inode号,因此他们一定指向同一块物理存储区。除此之外硬链接和源文件的的链接数都为2。
这是因为当为文件每创建一个硬链接, inode 节点上的链接数就会加一,每删除一个硬接, inode 节点上的链接数就会减一,直到为 0, inode 节点和对应的数据块才会被文件系统所回收,也就意味着文件已经从文件系统中被删除了。
现在删除掉硬链接可以发现链接数变为1。
软链接文件与源文件有着不同的 inode 号,所以也就是意味着它们之间有着不同的数据块,但是软链接文件的数据块中存储的是源文件的路径名,链接文件可以通过这个路径找到被链接的源文件,它们之间类似于一种“主从”关系,当源文件被删除之后,软链接文件依然存在,但此时它指向的是一个无效的文件路径, 这种链接文件被称为悬空链接,删除源文件后如图所示:
对于硬链接来说, 存在一些限制情况,如下:
⚫ 不能对目录创建硬链接(超级用户可以创建,但必须在底层文件系统支持的情况下)。
⚫ 硬链接通常要求链接文件和源文件位于同一文件系统中。
而软链接文件的使用并没有上述限制条件,优点如下所示:
⚫ 可以对目录创建软链接;
⚫ 可以跨越不同文件系统;
⚫ 可以对不存在的文件创建软链接。
创建链接文件
在 Linux 系统下,可以使用系统调用创建硬链接文件或软链接文件。
创建硬链接 link()
link()系统调用用于创建硬链接文件,函数原型如下(可通过"man 2 link"命令查看):
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
首先,使用该函数需要包含头文件<unistd.h>。
函数原型和返回值含义如下:
oldpath: 用于指定被链接的源文件路径,应避免 oldpath 参数指定为软链接文件,为软链接文件创建硬
链接没有意义,虽然并不会报错。
newpath: 用于指定硬链接文件路径,如果 newpath 指定的文件路径已存在,则会产生错误。
返回值: 成功返回 0;失败将返回-1,并且会设置 errno。
link()函数测试:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ret;
ret = link("./test", "./hard");
if (-1 == ret) {
perror("link error");
exit(-1);
}
exit(0);
}
此代码的作用是创建一个硬链接将hard与test链接起来。代码效果如下:可以发现创建完硬链接对应的链接数为2。
创建软链接 symlink()
symlink()系统调用用于创建软链接文件,函数原型如下(可通过"man 2 symlink"命令查看):
#include <unistd.h>
int symlink(const char *target, const char *linkpath);
首先,使用该函数需要包含头文件<unistd.h>。
函数参数和返回值含义如下:
target: 用于指定被链接的源文件路径, target 参数指定的也可以是一个软链接文件。
linkpath: 用于指定硬链接文件路径,如果 newpath 指定的文件路径已存在,则会产生错误。
返回值: 成功返回 0;失败将返回-1,并会设置 errno。
创建软链接时,并不要求 target 参数指定的文件路径已经存在,如果文件不存在,那么创建的软链接将
成为“悬空链接”
symlink 函数测试:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int ret;
ret = symlink("./test", "./soft");
if (-1 == ret) {
perror("symlink error");
exit(-1);
}
exit(0);
}
此代码的作用是创建一个软链接将soft与test链接起来。代码效果如下:
读取软链接文件 :
软链接文件数据块中存储的是被链接文件的路径信息,如果需要读取软链接的路径信息需要使用readlink函数。
readlink 函数原型如下所示:
#include <unistd.h>
ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
函数参数和返回值含义如下:
pathname: 需要读取的软链接文件路径。 只能是软链接文件路径,不能是其它类型文件,否则调用函
数将报错。
buf: 用于存放路径信息的缓冲区。
bufsiz: 读取大小,一般读取的大小需要大于链接文件数据块中存储的文件路径信息字节大小。
返回值: 失败将返回-1,并会设置 errno;成功将返回读取到的字节数。
readlink 函数测试:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
char buf[50];
int ret;
memset(buf, 0x0, sizeof(buf));
ret = readlink("./soft", buf, sizeof(buf));
if (-1 == ret) {
perror("readlink error");
exit(-1);
}
printf("%s\n", buf);
exit(0);
}
该函数的作用是打印出软链接soft的链接路径。代码效果如下: