• 十三、文件和目录——软链接和硬链接


    13.1 软链接和硬链接介绍

    13.1.1 软硬链接的创建

      通过 ln 命令可以对文件创建软硬链接

      创建硬链接 

      

      2 表示链接数

      创建软链接

      

      通过 ls -l  命令显示的文件类型为 l,表示文件类型为符号链接

    • 若删除原始文件,对硬链接来说依然可以查看到文件内容,只不过链接数会减1,对软链接来说,则链接依然存在,但是查看不到文件内容了,用 cat  和 more 命令的时候,会提示没有哪个文件或目录。

    13.1.2 软硬链接在Linux系统中的存放

      创建硬链接的时候,只是多创建了一个目录项,并不会创建一个 i 节点和数据块,然后链接数 +1。只有直到硬链接数为0的时候,才会释放这个文件,即真正的删除。

      创建硬链接,数据块存放的是源文件的路径,所以当源文件删除后,就找不到软链接的内容了。但是 i 节点和数据块还存在。软链接的链接数永远都是1。

      

    13.2 硬链接函数

    • 硬链接创建条件
      • 针对文件创建链接,无法对目录进行创建,除非是 root 用户
      • 必须是同一个分区
      • 只有超级用户才能对目录建立连接
    • 文件删除条件
      • 链接计数为0
      • 无其他进程打开该文件  

    13.2.1 创建链接-link 函数

      link(建立文件连接)
      相关函数 symlink,unlink

    1 #include <unistd.h>
    2 int link (const char * oldpath, const char * newpath);
    • 函数说明
      • link()以参数 newpath 指定的名称来建立一个新的连接(硬连接)到参数 oldpath 所指定的已存在文件。
      • 如果参数 newpath 指定的名称为一已存在的文件则不会建立连接。
    • 函数功能:
      • 创建一个指向现存文件的连接(硬链接)
    • 附加说明
      • link()所建立的硬连接无法跨越不同文件系统,如果需要请改用 symlink()。
    • 返回值
      • 成功则返回0,失败返回-1,错误原因存于errno。
    • 附加说明
      • link()所建立的硬连接无法跨越不同文件系统,如果需要请改用 symlink()。
    • 错误代码
      • EXDEV 参数 oldpath 与 newpath 不是建立在同一文件系统。
      • EPERM 参数 oldpath 与 newpath 所指的文件系统不支持硬连接
      • EROFS 文件存在于只读文件系统内
      • EFAULT 参数 oldpath 或 newpath 指针超出可存取内存空间。
      • ENAMETOLLONG 参数 oldpath 或 newpath 太长
      • ENOMEM 核心内存不足
      • EEXIST 参数 newpath 所指的文件名已存在。
      • EMLINK 参数 oldpath 所指的文件已达最大连接数目。
      • ELOOP 参数 pathname 有过多符号连接问题
      • ENOSPC 文件系统的剩余空间不足。
      •   EIO I/O 存取错误。 

    13.2.2 删除链接

      unlink(删除文件)
      相关函数 link,rename,remove

    1 #include <unistd.h>
    2 int unlink(const char * pathname);
    • 函数说明
      • unlink()会删除参数 pathname 指定的文件。
      • 如果该文件名为最后连接点,但有其他进程打开了此文件,则在所有关于此文件的文件描述词皆关闭后才会删除。
      • 如果参数 pathname 为一符号连接,则此连接会被删除。
    • 函数功能:
      • 删除 pathname 指定的硬链接(源文件和指定的硬链接文件都可以),并将由 pathname 所引用的文件链接计数减1  
    • 返回值
      • 成功则返回0,失败返回-1,错误原因存于errno
    • 错误代码
      • EROFS 文件存在于只读文件系统内
      • EFAULT 参数 pathname 指针超出可存取内存空间
      • ENAMETOOLONG 参数 pathname 太长
      • ENOMEM 核心内存不足
      • ELOOP 参数 pathname 有过多符号连接问题
      • EIO I/O 存取错误

    13.2.3 remove 函数

      remove(删除文件)
      相关函数 link,rename,unlink

    1 #include <stdio.h>
    2 int remove(const char * pathname);
    • 函数说明
      • remove()会删除参数 pathname 指定的文件。
      • 如果参数 pathname 为一文件,则调用 unlink() 处理,若参数 pathname 为一目录,则调用 rmdir() 来处理。请参考 unlink() 与 rmdir()。
      • 对于文件,remove 的功能与 unlink 相同
      • 对于目录,remove 的功能与 rmdir 相同
    • 函数功能:
      • 解除一个文件或目录的链接
    • 返回值
      • 成功则返回0,失败则返回-1,错误原因存于errno。
    • 错误代码
      • EROFS 欲写入的文件存在于只读文件系统内
      • EFAULT 参数 pathname 指针超出可存取内存空间
      • ENAMETOOLONG 参数 pathname 太长
      • ENOMEM 核心内存不足
      • ELOOP 参数 pathname 有过多符号连接问题
      • EIO I/O 存取错误

    13.2.4 rename 函数

      rename(更改文件名称或位置)
      相关函数 link,unlink,symlink

    1 #include <stdio.h>
    2 int rename(const char * oldpath, const char * newpath);
    • 函数说明
      • rename() 会将参数 oldpath 所指定的文件名称改为参数 newpath 所指的文件名称。若 newpath 所指定的文件已存在,则会被删除。
    • 函数功能:
      • 文件或目录更名
    • 返回值
      • 执行成功则返回0,失败返回-1,错误原因存于errno

    13.2.5 例子

      (1)硬链接的创建

      file_hardlink.c

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 #include <fcntl.h>
     5 #include <string.h>
     6 
     7 int main(int argc, char *argv[])
     8 {
     9     if(argc < 0) {
    10         fprintf(stderr, "usage:%s srcfile files
    ", argv[0]);
    11         exit(1);
    12     }
    13 
    14     int i;
    15 
    16     for(i = 2; i < argc; i++){
    17         if(link(argv[1], argv[i]) < 0) {
    18             perror("link error");
    19             continue;
    20         }
    21     }
    22 
    23     printf("create success
    ");
    24     return 0;
    25 }

      编译执行如下:

      

      

    13.3 软链接(即符号链接)

    13.3.1 创建软链接

    (1)创建软链接

      symlink(建立文件符号连接)
      相关函数 link,unlink

    1 #include <unistd.h>
    2 int symlink( const char * oldpath, const char * newpath);
    • 函数说明
      • symlink() 以参数 newpath 指定的名称来建立一个新的连接(符号连接)到参数 oldpath 所指定的已存在文件。
      • 参数 oldpath 指定的文件不一定要存在,如果参数 newpath 指定的名称为一已存在的文件则不会建立连接。
      • 创建符号链接并不要求 oldpath 的存在
      • 可以跨文件系统建立符号链接
      • 软链接可以针对目录进行创建
    • 函数功能
      • 创建一个符号链接(软链接)
    • 返回值
      • 成功则返回0,失败返回-1,错误原因存于errno。
    • 错误代码
      • EPERM 参数 oldpath 与 newpath 所指的文件系统不支持符号连接
      • EROFS 欲测试写入权限的文件存在于只读文件系统内
      • EFAULT 参数 oldpath 或 newpath 指针超出可存取内存空间。
      • ENAMETOOLONG 参数 oldpath 或 newpath 太长
      • ENOMEM 核心内存不足
      • EEXIST 参数 newpath 所指的文件名已存在。
      • EMLINK 参数 oldpath 所指的文件已达到最大连接数目
      • ELOOP 参数 pathname 有过多符号连接问题
      • ENOSPC 文件系统的剩余空间不足
      • EIO I/O 存取错误

    (2)读取软链接

      readlink(取得符号连接所指的文件)
      相关函数 stat,lstat,symlink

    1 #include <unistd.h>
    2 ssize_t readlink(const char * path ,char * buf,size_t bufsiz);
    • 函数说明
      • readlink()会将参数 path 的符号连接内容存到参数 buf 所指的内存空间,返回的内容不是以 NULL 作字符串结尾,但会将字符串的字符数返回。若参数 bufsiz 小于符号连接的内容长度,过长的内容会被截断。
    • 函数功能
      • 打开该链接本身,并读该链接中的名字(源文件的路径)
    • 返回值
      • 成功则返回读到的字节数,失败则返回-1,错误代码存于errno。
    • 错误代码
      • EACCESS 取文件时被拒绝,权限不够
      • EINVAL 参数 bufsiz 为负数
      • EIO I/O 存取错误。
      • ELOOP 欲打开的文件有过多符号连接问题。
      • ENAMETOOLONG 参数 path 的路径名称太长
      • ENOENT 参数 path 所指定的文件不存在
      • ENOMEM 核心内存不足
      • ENOTDIR 参数 path 路径中的目录存在但却非真正的目录。

    13.3.2 例子

      file_link.c

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <fcntl.h>
     4 #include <stdlib.h>
     5 #include <errno.h>
     6 #include <unistd.h>
     7 
     8 int main(int argc, char *argv[])
     9 {
    10     if(argc < 3) {
    11         fprintf(stderr, "usage:%s srcfile linkfiles
    ", argv[0]);
    12         exit(1);
    13     }
    14 
    15     //对源文件创建符号链接(软链接)
    16     if(symlink(argv[1], argv[2]) < 0) {
    17         perror("symlink error");
    18         exit(1);
    19     }
    20 
    21     //读取软链接引用的源文件的内容
    22     char buff[4096];
    23     ssize_t size;
    24     memset(buff, 0, sizeof(buff));
    25     int fd = open(argv[2], O_RDONLY);
    26     if(fd < 0) {
    27         perror("open error");
    28         exit(1);
    29     }
    30 
    31     if((size = read(fd, buff, sizeof(buff))) < 0) {
    32         perror("read error");
    33         exit(1);
    34     } else {
    35         write(STDOUT_FILENO, buff, size);
    36     }
    37 
    38     printf("
    ");
    39 
    40     //读取软链接本身的内容
    41     memset(buff, 0, sizeof(buff));
    42     if((size = readlink(argv[2], buff, sizeof(buff))) < 0) {
    43         perror("readlink error");
    44         exit(1);
    45     } else {
    46         write(STDOUT_FILENO, buff, size);
    47     }
    48 
    49     printf("
    ");
    50 
    51     return 0;
    52 }

       编译执行

      

  • 相关阅读:
    Postman模拟后端服务(mock server)
    Fiddler常用的几个功能
    Postman常用的几个功能
    Postman常用功能详解,常用请求方法
    sql小技巧
    postman接口数据关联
    postman批量发送多个请求
    sql去重查询语句
    pytho接口自动化-session
    charles抓包使用教程
  • 原文地址:https://www.cnblogs.com/kele-dad/p/9064993.html
Copyright © 2020-2023  润新知