嵌入式Linux系统编程 — 3.6 软连接与硬连接详解

目录

1 软连接和硬连接

1.1 软连接(Symbolic Links,简称Symlinks)

1.2 硬连接(Hard Links)

1.3 硬连接和软连接的区别

2 link()创建硬链接

2.1 link()函数简介

2.2 示例程序

3 symlink()函数

4 读取软连接文件

4.1 readlink()函数简介

4.2 示例程序


1 软连接和硬连接

在Linux系统中,"连接"(links)是一种文件系统对象,它可以指向另一个文件或目录。有两种主要类型的连接:硬连接(hard links)和软连接(也称为符号链接,symbolic links)。

1.1 软连接(Symbolic Links,简称Symlinks)

软连接是一种特殊的文件,它包含了指向另一个文件或目录的路径。软连接更像是一个快捷方式。软连接的特点包括:

  • 软连接可以跨文件系统创建。
  • 软连接可以指向文件或目录。
  • 删除软连接不会影响原始文件或目录。如果软连接指向的目标被移动或删除,软连接将变成一个悬空链接(dangling link)。
  • 软连接是独立的文件,有自己的权限和inode。

创建软连接的命令是ln,使用-s选项:

ln -s target_path new_symlink_name

 为了说理解硬连接的概念, 先来创建一个软链接文件,如下所示:

软链接文件与源文件有着不同的 inode 号, 如图所示, 所以也就是意味着它们之间有着不同的数据块,但是软链接文件的数据块中存储的是源文件的路径名,链接文件可以通过这个路径找到被链接的源文件,它们之间类似于一种“主从”关系,当源文件被删除之后,软链接文件依然存在,但此时它指向的是一个无效的文件路径, 这种链接文件被称为悬空链接

1.2 硬连接(Hard Links)

硬连接是指向相同inode的多个文件名。创建硬连接后,文件就拥有了多个名称,但它们实际上是同一个文件。硬连接的特点包括:

  • 硬连接不能跨文件系统创建。
  • 硬连接可以指向目录。
  • 删除硬连接不会影响原始文件,只有当所有硬连接都被删除后,文件数据才会被删除。

创建硬连接的命令是ln,使用-s选项可以创建硬连接:

ln file_to_link new_link_name

为了说理解硬连接的概念, 先来创建一个硬链接文件,如下所

从图中可知,使用 ln 命令创建的两个硬链接文件与源文件 test_file.c 都拥有相同的 inode 号, 既然inode 相同,也就意味着它们指向了物理硬盘的同一个区块,仅仅只是文件名字不同而已,创建出来的硬链接文件与源文件对文件系统来说是完全平等的关系。

当我们删除其中任何一个文件后,链接数就会减少,如下所示:

1.3 硬连接和软连接的区别

  • 存储方式:硬连接直接指向inode,而软连接存储的是目标的路径字符串。
  • 跨文件系统:硬连接不能跨文件系统,软连接可以。
  • 删除行为:删除硬连接不会影响原始文件,软连接的删除不影响目标文件。
  • 更新行为:如果目标文件被移动或重命名,硬连接仍然有效,软连接则可能需要更新。
  • 权限:硬连接的权限与原始文件相同,软连接有自己的权限设置。

2 link()创建硬链接

2.1 link()函数简介

link()系统调用用于创建硬链接文件,函数原型如下:

#include <unistd.h> 

int link(const char *oldpath, const char *newpath);
  • oldpath:指向一个以null结尾的字符串,表示源文件的路径。
  • newpath:指向一个以null结尾的字符串,表示新硬链接的路径。

2.2 示例程序

下面的示例程序接受两个命令行参数,源文件名和硬链接的文件名,并尝试创建一个硬链接:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char *argv[]) {
    // 检查是否传入了两个参数
    if (argc != 3) {
        fprintf(stderr, "Usage: %s source_filename link_filename\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    const char *source_filename = argv[1];  // 源文件名
    const char *link_filename = argv[2];    // 硬链接名

    // 使用link()函数创建硬链接
    if (link(source_filename, link_filename) == -1) {
        // 如果link()调用失败,打印错误信息并退出程序
        perror("Error creating hard link");
        exit(EXIT_FAILURE);
    }

    printf("Hard link '%s' created for '%s' successfully.\n", link_filename, source_filename);
    return 0;
}

程序首先检查是否传入了正确的参数数量。如果不是,它会打印出正确的用法并退出。如果参数数量正确,它会尝试创建硬链接。运行的结果与ln命令相同,如下:

3 symlink()函数

symlink() 函数在Linux系统中用于创建软链接。与硬链接不同,符号链接有自己的inode,并且可以指向文件系统之外的文件或目录。symlink() 函数的原型如下:

#include <unistd.h> 

int symlink(const char *oldpath, const char *newpath);
  • oldpath:指向一个以null结尾的字符串,表示源文件或目录的路径,这是符号链接将要指向的目标。
  • newpath:指向一个以null结尾的字符串,表示新符号链接的路径。

示例程序可以将上面的link()函数换为symlink()函数。

4 读取软连接文件

4.1 readlink()函数简介

readlink() 函数在Linux系统中用于读取软链接指向的目标路径。它允许你获取软链接指向的文件或目录的实际路径。readlink() 函数的原型如下:

#include <unistd.h> 

ssize_t readlink(const char *path, char *buf, size_t bufsiz);
  • path:需要读取的软链接文件路径。 只能是软链接文件路径,不能是其它类型文件,否则调用函数将报错。
  • buf:用于存放路径信息的缓冲区。
  • bufsiz:读取大小,一般读取的大小需要大于链接文件数据块中存储的文件路径信息字节大小。

4.2 示例程序

readlink() 函数在Linux系统中用于读取软链接指向的目标路径,示例程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char *argv[]) {
    // 检查是否传入了两个参数
    if (argc != 3) {
        fprintf(stderr, "Usage: %s symlink_path buffer_size\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    const char *symlink_path = argv[1]; // 符号链接的路径
    size_t buf_size = atoi(argv[2]);    // 缓冲区大小
    char *buf = malloc(buf_size);       // 动态分配缓冲区

    if (!buf) {
        perror("Memory allocation failed");
        exit(EXIT_FAILURE);
    }

    // 使用readlink()函数读取符号链接
    ssize_t len = readlink(symlink_path, buf, buf_size);
    if (len == -1) {
        // 如果readlink()调用失败,打印错误信息并释放内存
        perror("Error reading symbolic link");
        free(buf);
        exit(EXIT_FAILURE);
    }

    // 确保字符串以空字符结尾
    buf[len] = '\0';

    printf("Symbolic link '%s' points to '%s'\n", symlink_path, buf);
    free(buf); // 释放缓冲区
    return 0;
}

程序它读取第二个参数作为符号链接的路径,第三个参数作为缓冲区的大小,并使用 atoi() 函数将其转换为整数。接下来程序使用 malloc() 动态分配一个大小为 buf_size 的缓冲区来存储从readlink() 读取的路径。如果 readlink() 成功,它将返回读取的字节数,并将缓冲区中的字符串以空字符结尾。然后,程序打印出符号链接指向的目标路径,并在完成之后释放缓冲区。注意传入的是软连接文件而不是原文件,运行结果如下:

  • 14
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

几度春风里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值