什么是硬链接

struct stat {nlink_t   st_nlink;       /* Number of hard links};

stat结构体就有一个成员变量----硬链接数

  • 使用ln命令就可以创建硬链接

  • 创建硬链接,就是再为文件创建一个名字

每创建一个硬链接,文件就多一个文件名,硬件链接数+1

  • 多个文件名指向了同一个文件,操作文件时,使用任何一个名字都可以

创建硬链接后所得到的多个文件名,指向的同一个inode节点,只有inode节点代表了文件的真实存在,inode节点只有一个,因此多个文件名指向的是同一个文件,不管使用的是哪一个文件名,都能操作这个文件。

硬链接数

  • 记录了有多少个文件名指向了inode节点,通过创建硬链接,每增加一个文件名,就多一个硬链接数
  • 同理,每删除一个硬链接,也就是删除一个文件名,就少一个硬链接数

删除文件时,只是将文件的inode节点空间释放了,如果这个文件有数据的话,那么这个文件的数据仍然还在,在这种情况下,只要将文件的inode节点空间恢复,即可还原该文件。

如图,新创建的目录的硬链接数是2.

因为新创建的目录,一开始就有两个名字指向了目录的inode节点,分别是目录的本名text和.

  • 在该目录下,每多创建一个目录,当前目录就会多一个硬链数

Linux不允许用户自己给目录创建硬链接,只能由Linux系统自己给目录创建硬链接

用户只能给目录以外的,其它类型的文件创建硬链接

目录

目录是特殊的文件,本质上是一个表格,用于存储文件名和inode节点空间

可以在目录中创建多个链接指向文件,这些链接指向相同的inode节点空间

link函数

#include <unistd.h>
//功能:为非目录文件建立一个新的硬连接(ln命令就是调用这个系统函数来实现的)
//返回值:调用成功返回0,失败返回-1,errno被设置
int link(const char *oldpath, const char *newpath);
 link("./mm.txt","./mm1.txt");

unlink函数

#include <unistd.h>
//功能:删除一个硬连接,其实就是删除一个名字。
//返回值:调用成功返回0,失败返回-1,errno被设置
//参数:pathname:要删除路径名
int unlink(const char *pathname);

只能用于删除非目录文件的硬链接,不能删除目录的硬链接,Linux系统不允许用户修改目录的硬件链接

使用unlink创建临时文件

临时文件:

  • 只在程序运行过程中有效,程序运行结束后就自动删除

  • 使用unlink就可以实现一个临时文件

open创建一个文件后(新文件的硬链接数都是1),然后立即调用unlink将文件硬链接数减为0,将其删除。

虽然文件的硬链接数变成了0,但是在进程没有结束之前,这个文件仍然可以被使用,直到进程结束后,文件才被删除

#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(){int fd=open("mm.txt",O_RDWR|O_CREAT,0664);if(fd==-1){perror("open fail!");exit(-1);}unlink("./mm.txt");write(fd,"hello,world!\n",12);lseek(fd,0,SEEK_SET);char buf[30]={0};read(fd,buf,sizeof(buf));printf("buf=%s\n",buf);return 0;
}

remove函数

#include <stdio.h>
//功能:可以用于删除任何文件(既可以删除目录文件,也可以删除非目录文件)
//删除非目录文件时,功能与unlink一样。
//返回值:调用成功返回0,失败返回-1,errno被设置
int remove(const char *pathname);
int main(){remove("./aaa");//删除目录aaareturn 0;
}

rename函数

mv命令

  • 改名
  • 移动
  • 移动+改名

mv ./mm.txt …/mm_aa.txt

#include <stdio.h>
//功能:修改文件路径名,将旧的路径名oldpath,改为新的路径名newpath
//返回值:调用成功返回0,失败返回-1,errno被设置
int rename(const char *oldpath, const char *newpath);
rename("./mm_aa.txt","./aaa/mm.txt");//使用

如果文件移动起始位置和目标位置,在同一个分区里面的话

移动文件时,不会移动文件的数据;

只是把文件的基本信息(名字、inode编号),从这个目录记录到另一个目录下。

什么是符号链接

符号链接文件也被称为软链接文件

使用ln -s就可以创建符号链接文件

  • 符号链接文件就是一个快捷图标,它指向了另一个文件

和windows一样,原文件被删除了,快捷指向就没意义了


软链接和硬链接的对比

  • 创建硬连接

    同一个文件有多个不同的名字,它们指向是同一个inode节点

  • 创建符号链接文件

    符号链接文件与它所指向的文件,是两个完全不同的独立的文件,拥有自己独立的inode节点。

    符号链接文件的数据就是指向文件的文件名,文件大小就是名字的字符个数

不能给目录创建硬链接,但是可以给目录创建符号链接;只要你有需要,可以给任何文件创建符号链接文件。而且可以给符号链接文件,创建硬链接

s_link是link目录的软链接,p_s_link是s_link的硬链接

symlink

#include <unistd.h>
//功能:为oldpath,创建符号连接文件newpath
//函数返回值:调用成功返回0,失败返回-1,errno被设置
int symlink(const char *target, const char *linkpath);

使用ln创建硬链接时,调用的是link函数; 使用ln -s创建符号链接时,调用的是symlink

readlink

#include <unistd.h>
//功能:读符号链接文件的数据(指向文件的名字)
/*1)const char *path:符号连接文件的路径名。2)char *buf:存放名字缓存的地址。3)size_t bufsiz:缓存的大小
*/
//返回值:调用成功,返回读到的字节数,失败返回-1,errno被设置
ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);

int main(){symlink("./link.c","slink");char buf[30]={0};readlink("./slink",buf,sizeof(buf));printf("buf=%s\n",buf);return 0;
}

stat半成品

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void print_error(char *str){perror(str);exit(-1);
}int main(int argc, char **argv){int ret = 0;int i = 0;struct stat sta = {0};if(argc != 2){printf("./a.out fileName\n\n");exit(-1);}/* 获取文件属性 */ret = lstat(argv[1], &sta);if(-1 == ret) print_error("stat fail");/* 打印文件类型 */char file_type = '0';   if(S_ISLNK(sta.st_mode)) file_type = 'l'; else if(S_ISREG(sta.st_mode)) file_type = '-';else if(S_ISDIR(sta.st_mode)) file_type = 'd';else if(S_ISCHR(sta.st_mode)) file_type = 'c';else if(S_ISBLK(sta.st_mode)) file_type = 'b';else if(S_ISFIFO(sta.st_mode)) file_type = 'p';else if(S_ISSOCK(sta.st_mode)) file_type = 's';printf("%c", file_type);/* 打印文件权限 */ char buf[10] = {0};char tmp_buf[] = "rwxrwxrwx";for(i=0; i<9; i++){if(sta.st_mode & (1<<(8-i))) buf[i] = tmp_buf[i];else buf[i] = '-';}printf("%s", buf);/* 打印文件属性 */printf(" %lu %u %d %ld %ld %s", sta.st_nlink, \sta.st_uid, sta.st_gid, sta.st_size, sta.st_atime, argv[1]);//打印出链接文件的指向if(file_type=='l'){char mm[30]={0};readlink(argv[1],mm,sizeof(mm));printf("->%s\n",mm);}else printf("\n");return 0;
}

符号跟随函数 与 符号不跟随函数

(1) 符号跟随函数

调用某个函数操作文件,当指定的路径名是符号链接文件时:

如果函数最后操作的是符号链接文件所指向的文件,而不是“符号链接文件”本身,

这个函数就是符号跟随函数,因为它跟到符号链接文件所指向的背后去了。

  • 比如stat、open就是符号跟随函数,因为这些操作的都是符号链接文件所指向的文件

(2)符号不跟随函数

当路径名是符号链接文件时,函数操作的就是符号链接文件本身,不会跟随

比如lstat就是符号不跟随函数,因为获取文件属性时,如果操作的是符号链接文件的话,那么获取的是符号链接文本身的属性。

  • 凡是需要指定“文件路径名”函数,只要函数名字是l打头的,比如像lstat,基本都是符号不跟随函数。
  • lseek不需要指定路径名,而是通过文件描述符(fd)操作的,不存在符号跟随与不跟随的问题。

getcwd

#include <unistd.h>
//这是一个库函数,执行pwd命令就是调用这个函数实现的
//功能:获取进程的当前工作目录
/*参数1)buf:存放获取到的当前路径的缓存2)size:缓存的大小
*/
char *getcwd(char *buf, size_t size);
int main(){char buf[30]={0};char *p=getcwd(buf,100);printf("pwd=%s\n",buf);printf("p=%p,buf=%p\n",p,buf);return 0;
}
/*执行结果:
pwd=/home/guojiawei/Desktop/link
p=0x7ffe8d093ac0,buf=0x7ffe8d093ac0
getcwd的返回值是存放路径的地址
*/

chdir

change chdir

#include <unistd.h>
//功能:切换进程当前工作目录到path。
int chdir(const char *path);
int main()
{char buf[30] = {0};char *p = getcwd(buf, 100);printf("pwd=%s\n", buf);chdir("../");getcwd(buf, 100);printf("pwd_cur=%s\n", buf);return 0;
}
/*执行结果:
pwd=/home/guojiawei/Desktop/link
pwd_cur=/home/guojiawei/Desktop
*/

cd命令就是调用chdir的命令

mkdir

#include <sys/stat.h>
#include <sys/types.h>
//功能:创建新目录。
/*参数:1)pathname:需创建目录的路径名2)mode:指定目录的原始权限,一般给0775
*/
int mkdir(const char *pathname, mode_t mode);

给目录指定原始权限时,一定要有x权限,否者无法进入这个目录

rmdir

rm命令删除目录时,调用的都是rmdir这个函数

  • rmdir命令:只能删除空目录,rmdir命令用的很少
  • rm:不管目录空不空,都能删除,rm用的最多
                  rm|remove|     ||     |/       \/         \unlink       rmdir
#include <unistd.h>
//函数功能:删除路径名为pathname的这个目录
int rmdir(const char *pathname);

删除时,Linux系统会调用相关函数,将目录硬链数全部减位0,然后目录就被删除了

如果目录不为空,必须递归调用rmdir函数,实现递归删除

opendir和readdir

  • opendir:打开目录,以便调用readdir读取目录项
  • readdir:读取目录里面的目录项

目录项:
目录里面的数据,其实就是一条一条的目录项,每个目录项就是一个文件的基本信息

文件基本信息:文件名inode节点号

不能使用open函数打开目录,只能使用opendir打开

#include <sys/types.h>
#include <dirent.h>
//功能:打开目录
//参数:name---需打开目录的路径名
/*返回值:调用成功:返回一个DIR *的指针,这个指针指向了被打开的目录,readdir通过这个指针就可以读取目录的目录项。调用失败:返回NULL,errno被设置。
*/
DIR *opendir(const char *name);
#include <dirent.h>
//功能:读取目录里的目录项-----每调用一次,就读取出一条目录项。
//参数dirp:opendir打开目录时,得到的指针。
//返回值:调用成功,返回指针指向struct dirent结构体的指针
/*
返回NULL的话有如下两种情况:1)读到目录的末尾时,返回NULL。2)函数调用失败时,也返回NULL,不过errno被设置。
*/
struct dirent *readdir(DIR *dirp);
  • 结构体 struct dirent

    这个结构体就是用来存放一条目录项的:

    调用readdir读取到目录项后,会自动开辟一个struct dirent变量来存放目录项,然后将变量的指针返回;

    应用程序通过这个指针,就可以访问结构体中的目录项信息(文件基本信息)。

    struct dirent {ino_t          d_ino;       /* Inode number */off_t          d_off;       /* Not an offset; see below */unsigned short d_reclen;    /* Length of this record */unsigned char  d_type;      /* Type of file; not supportedby all filesystem types */char           d_name[256]; /* Null-terminated filename */};
    //最重要的就是:inode编号和文件名
    

    怎么判断函数是否调用失败了呢?

    • 如果ernno==0,表示没有设置错误号,返回NULL是因为读到了文件的末尾。
    • 如果errno!=0,表示是因为函数调用出错而返回的NULL。
#include <stdio.h>
#include <stdlib.h>
//opendir头文件
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>int main(){DIR *pot=opendir(".");if(pot==NULL){perror("opendir fails!");exit(-1);}while(1){//循环读struct dirent *dir_p=readdir(pot);if(dir_p==NULL && errno!=0){perror("readdir fails\n");}if(dir_p==NULL && errno==0) break;//读到末尾printf("inode=%lu,fname=%s\n",dir_p->d_ino,dir_p->d_name);}return 0;
}

chmod 和 fchmod

#include <sys/stat.h>
//功能:修改文件权限
//chmod:使用路径名操作
//fchmod:使用文件描述符操作
int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);

硬链接,软链接,link,rename,symlink,opendir和readdir相关推荐

  1. 软链接(Soft Link,符号链接)和硬链接(Hard Link)。

    目录 引言 创建软连接,硬链接 创建语句 二者区别 引言 链接是一种在共享文件和访问它的用户的若干目录项之间建立联系的一种方法.方便文件的共享使用,在Linux操作系统中引入了连接,链接被分为两种:软 ...

  2. Windows下mklink使用, 硬链接, 软链接和快捷方式的区别

    Windows下mklink使用,   硬链接, 软链接和快捷方式的区别 mklink是windows系统下创建符号链接和硬链接的命令工具,它是一个很好的解决文件系统问题的工具.使用它需要管理员权限. ...

  3. linux 的文件软链接隐藏,Linux inode及硬链接软链接详解

    Linux inode及硬链接软链接详解 York • 2020 年 09 月 28 日 Loading... 操作系统的文件数据除了实际内容之外,通常含有非常多的属性,例如 `Linux`操作系统的 ...

  4. linux 硬链接 软链接_Linux中的软链接–完整参考

    linux 硬链接 软链接 A link in Linux systems are pointers to a file or a directory. There are two types of ...

  5. linux 硬链接 软链接 简介

    在linux系统中有种文件是链接文件,可以为解决文件的共享使用.链接的方式可以分为两种,一种是硬链接(Hard Link),另一种是软链接或者也称为符号链接(Symbolic Link). 查看lin ...

  6. Linux硬链接 软链接

    1.Linux链接概念 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接] 硬连接指通过索引 ...

  7. 深入理解linux文件系统( 理解inode与block,理解硬链接软链接,掌握恢复误删文件及其分析方法,掌握用户日志及其查询命令 )

    文章目录 深入理解linux文件系统 前言 inode与block详解 inode和bolck概述 1:数据(block)块: 2:元信息 : inode(索引节点) inodu的内容 Linux系统 ...

  8. Linux 硬链接软链接

    LINUX 下的链接文件有点类似于Windows的快捷方式,但又不完全一样. 链接文件有两种:一种是硬链接,另一种是符号链接(又称软链接). 硬链接类似于复制了一个新的文件,这个文件不会随着源文件的丢 ...

  9. 硬链接与软链接的区别有哪些?

    首先,大家要理解如下的概念: 在Linux系统中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号. 文件属性保存在索引结点里,在访问文件时,索引结点被复制到 ...

最新文章

  1. 智源论坛Live丨青年科学家线上报告会日程发布
  2. php5.5.9 新特性,php,_PHP 5.5.9版本中COOKIE的奇怪现象,php - phpStudy
  3. evb测试板_做芯片 再“穷”不能“穷”测试
  4. 数据结构之直接插入排序图文详解及代码(C++实现)
  5. Vue3.0 组合式 API 分析与实践
  6. 【解题报告+通法】_九宫幻方 蓝桥杯 2017年C组第八题(dfs解法)
  7. flink启动出现java.lang.NoClassDefFoundError: org/apache/hadoop/fs/Path
  8. JDK1.8中如何用ScriptEngine动态执行JS
  9. 做个程序员身体调查,希望大家点一下!
  10. Unable to compile template. Check the Errors list for details 问题解决办法
  11. android 编译api,Android逆向利器,直接将apk转换为可二次开发Android工程,提供So hook Api,......
  12. HACCP的相关文献包含哪些?
  13. markdown颜色索引及表格背景颜色填充
  14. python任务栏通知区域_PyQT实现通知区域图标和对话气泡
  15. 《般若波罗蜜多心经》注解
  16. 毕业设计-基于微信小程序的医生随访系统
  17. 基于ITIL的医院信息化服务管理实践(客户说)
  18. 3.文件系统组成和基本操作
  19. python实现1/n倍频程计算
  20. C++程序设计课程同步项目——循环结构程序设计项目任务二

热门文章

  1. Vueg - 为 webApp 提供转场特效的开源 Vue 插件
  2. 机房装修施工详解!干货收藏
  3. python中用类名访问的方法_对于 Python类中的私有成员,可以通过“对象名._类名__私有成员名”的方式来访问 答案:√...
  4. 埃里克森的社会心理发展阶段
  5. java毕业设计师范生说课作业提交平台源码+lw文档+mybatis+系统+mysql数据库+调试
  6. Elasticsearch:ingest pipelines - 使用技巧和窍门
  7. 202:vue+openlayers: easing的API及在view.animation中使用示例
  8. 春节档票房超30亿 互联网资本新旧势力赛跑
  9. vue 2.0需求拍摄证件照(需要设置人头取景框,鼠标也拖拽,键盘方向键可调整位置)
  10. java文件与流_Java文件与流