linux文件-link函数(文件硬链接和软连接)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/andrewgithub/article/details/82026727

创建硬链接的函数:

相关函数:symlink, unlink

头文件:#include <unistd.h>

定义函数:int link (const char * oldpath, const char * newpath);

函数说明:link函数中oldpath指定已经存在文件,newpath指定的名称建立一个新的连接(硬链接),若是newpath指定的文件已存在则不会建立连接;

头文件:#include <unistd.h>

定义函数:int unlink(const char * pathname);

unlink()会删除参数pathname 指定的文件. 如果该文件名为最后连接点, 但有其他进程打开了此文件, 则在所有关于此文件的文件描述词皆关闭后才会删除. 如果参数pathname 为一符号连接, 则此连接会被删除。

硬链接创建条件,创建的除非是root用户,否则创建硬链接只能是针对文件名字;

创建硬链接必须在同一个分区;

只有超级用户才能够对目录创建硬链接;

硬链接文件删除的过程是删除文件计数,文件硬链接计数为0的时候会删除文件,但是前提条件是没有其他进程打开该文件。

创建硬链接使用的命令: ln  oldfilename newfilename

andrew@andrew-Thurley:~/work/filedir$ ls -l name
-rw-rw-r-- 2 andrew andrew 43 8月  22 21:33 name
andrew@andrew-Thurley:~/work/filedir$ ls date.txt
date.txt
andrew@andrew-Thurley:~/work/filedir$ ls -l date.txt
-rw-rw-r-- 2 andrew andrew 43 8月  22 21:33 date.txt
andrew@andrew-Thurley:~/work/filedir$ ls -l a.out
-rwxrwxr-x 1 andrew andrew 8840 8月  24 23:10 a.out
andrew@andrew-Thurley:~/work/filedir$ 

创建硬链接之后显示硬链接文件是一个普通的文件,其中在权限说明之后显示的  的数字2说明的是文件的链接数。

-rwxrwxr-x 第一个 ‘-’指的是普通文件,然后徐后面的是,r可读,w可写,x可执行,分别u+g+o

若是删除源文件,硬链接还是能够看到文件的内容

硬链接创建共享同一个 i节点但是软连接创建的时候会生成自己的 i 节点。

创建硬链接只是创建了文件的连接数,有硬链接的文件当删除源文件的时候删除的只是文件的连接计数,并没有删除磁盘上的文件,创建硬链接也会造成连接数加1。删除文件的实质就是将文件的硬链接数减少到0,所以硬链接虽然没有在磁盘上创建文件,但是硬链接出来的文件名是跟源文件名同等的。 


    #include<unistd.h>
    int symlink(const char*actualpath,const char *sympath);
       #include <fcntl.h>           /* Definition of AT_* constants */
       #include <unistd.h>
     int symlinkat(const char *actualpath,int fd,const char *sympath);
                           两个函数返回值:若成功,返回0;若出错,返回-1


                           两个函数返回值:若成功,返回0;若出错,返回-1
ssize_t readlink(const char* restrict pathname,char *restrict buf,size_t bufsize);
ssize_t readlinkat(int fd,const char* restrict pathname,char *restrict buf,size_t bufsize);
                           两个函数返回值:若成功,返回读取的字节数;若出错,返回-1

symlink函数创建了一个指向actualpath的新目录项sympath。在创建此符号链接时,并不要求actualpath已经存在。并且actualpath和sympath并不需要位于同一文件系统中。

symlinkat函数与symlink函数类似,但sympath参数根据相对于打开文件描述符引用的目录(由fd指定)进行计算。如果sympath参数指定的是绝对路径或者fd参数设置了AT_FDCWD值,那么symlinkat就等同于symlink函数。

readlink和readlinkat函数组合了open、read和close的所有操作。如果函数成功执行,则返回读入buf的字节数。在buf中返回的符号链接的内容不以null字符终止。

当pathname参数指定的是绝对路径名或者fd参数的值为AT_FDCWD,readlinkat函数的行为与readlink相同。但是,如果fd参数是一个打开目录的有效文件描述符并且pathname参数是相对路径名,则readlinkat计算相对于由fd代表的打开目录的路径。

创建软连接:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#define BUFFSIZE 1024
 
int main(int argc,char *argv[])
{
    if(argc != 4){
        printf("param too few\n");
        exit(EXIT_FAILURE);
    }
 
    char buf[BUFFSIZE];
    ssize_t sz;
    DIR *dp;
    int fd;
 
    //获取相对路径名返回的文件描述符fd
    if((dp = opendir(argv[2])) == NULL){
        perror("opendir");
        exit(EXIT_FAILURE);
    }
    if((fd = dirfd(dp)) < 0){
        perror("dirfd");
        exit(EXIT_FAILURE);
    }
 
    //创建符号链接
    if(symlinkat(argv[1],fd,argv[3]) < 0){
        perror("symlinkat");
        exit(EXIT_FAILURE);
    }
 
    //读取符号链接
    bzero(buf,sizeof(buf));
    if((sz = readlinkat(fd,argv[3],buf,sizeof(buf))) < 0){
        perror("readlinkat");
        exit(EXIT_FAILURE);
    }
 
    printf("buf:%s,length:%u\n",buf,(unsigned int)sz);
    close(fd);
    return 0;
}

创建软连接:使用  ln -s oldfilename  newfilename

andrew@andrew-Thurley:~/work/filedir$ ln -s date1.txt s1_l
andrew@andrew-Thurley:~/work/filedir$ ls -l date1.txt  s1_l 
-rw-rw-r-- 1 andrew andrew 43 8月  25 00:03 date1.txt
lrwxrwxrwx 1 andrew andrew  9 8月  25 00:04 s1_l -> date1.txt
andrew@andrew-Thurley:~/work/filedir$ 

删除源文件软连接,就不能查看文件的内容,会提示是没有那个文件或目录;

创建软连接之后文件显示的文件连接数还是1

软连接就像windows上创建一个快捷方式一样;并且软连接会显示文件的类型是  l 也就是说明 文件是连接型的文件

软连接我文件创建可以跨分区创建符号连接,创建符号链接并不要求actualpath即原文件一定存在。

如图,左边是硬链接,右边是软连接;

硬链接只创建了目录项然后使i节点的硬链接计数加1,删除的时候也只是对i节点的连接计数减1, 软连接创建了目录项,i节点,数据块,但是数据块中存放的不是

源文件内容的复制,存放的是源文件路径,因此当源文件删除的时候,再去使用软连接软连接文件将提示文件不存在或已删除。

相关函数:

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

       int remove(const char *pathname);

对于文件remove的左右和unlink的作用是一样的,但是对于目录来说使用remove相当于使用rmdir 即删除目录。

#include <stdio.h>
	
int rename(char * oldname, char * newname);
函数rename()用于重命名文件、改变文件路径或更改目录名称。

oldname为旧文件名,newname为新文件名。

修改文件名成功则返回0,否则返回-1。

重命名文件:

    如果newname指定的文件存在,则会被删除。
    如果newname与oldname不在一个目录下,则相当于移动文件。

重命名目录:

    如果oldname和oldname都为目录,则重命名目录。
    如果newname指定的目录存在且为空目录,则先将newname删除。
    对于newname和oldname两个目录,调用进程必须有写权限。
    重命名目录时,newname不能包含oldname作为其路径前缀。例如,不能将/usr更名为/usr/foo/testdir,因为老名字( /usr/foo)是新名字的路径前缀,因而不能将其删除。

猜你喜欢

转载自blog.csdn.net/andrewgithub/article/details/82026727