Linux中link,unlink,close,fclose详解
2015-07-10 16:39
357 查看
每一个文件,都可以通过一个struct stat的结构体来获得文件信息,其中一个成员st_nlink代表文件的链接数。
当通过shell的touch命令或者在程序中open一个带有O_CREAT的不存在的文件时,文件的链接数为1。
通常open一个已存在的文件不会影响文件的链接数。open的作用只是使调用进程与文件之间建立一种访问关系,即open之后返回fd,调用进程可以通过fd来read 、write 、 ftruncate等等一系列对文件的操作。
close()就是消除这种调用进程与文件之间的访问关系。自然,不会影响文件的链接数。在调用close时,内核会检查打开该文件的进程数,如果此数为0,进一步检查文件的链接数,如果这个数也为0,那么就删除文件内容。
link函数创建一个新目录项,并且增加一个链接数。
unlink函数删除目录项,并且减少一个链接数。如果链接数达到0并且没有任何进程打开该文件,该文件内容才被真正删除。如果在unlilnk之前没有close,那么依旧可以访问文件内容。
综上所诉,真正影响链接数的操作是link、unlink以及open的创建。
删除文件内容的真正含义是文件的链接数为0,而这个操作的本质完成者是unlink。close能够实施删除文件内容的操作,必定是因为在close之前有一个unlink操作。
举个例子简单说明:
为保证有abc,先执行: touch abc, 然后编译运行:
当通过shell的touch命令或者在程序中open一个带有O_CREAT的不存在的文件时,文件的链接数为1。
通常open一个已存在的文件不会影响文件的链接数。open的作用只是使调用进程与文件之间建立一种访问关系,即open之后返回fd,调用进程可以通过fd来read 、write 、 ftruncate等等一系列对文件的操作。
close()就是消除这种调用进程与文件之间的访问关系。自然,不会影响文件的链接数。在调用close时,内核会检查打开该文件的进程数,如果此数为0,进一步检查文件的链接数,如果这个数也为0,那么就删除文件内容。
link函数创建一个新目录项,并且增加一个链接数。
unlink函数删除目录项,并且减少一个链接数。如果链接数达到0并且没有任何进程打开该文件,该文件内容才被真正删除。如果在unlilnk之前没有close,那么依旧可以访问文件内容。
综上所诉,真正影响链接数的操作是link、unlink以及open的创建。
删除文件内容的真正含义是文件的链接数为0,而这个操作的本质完成者是unlink。close能够实施删除文件内容的操作,必定是因为在close之前有一个unlink操作。
举个例子简单说明:
#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> int main() { int fd; //char buf[32]; struct stat buf; //没有打开文件之前线测试链接数 if(stat("abc", &buf) !=0) printf("stat file fail \n"); printf("1. link =%d \n", buf.st_nlink); //打开已经存在的abc fd = open("abc", O_RDONLY); stat("abc", &buf); printf("2. link =%d \n", buf.st_nlink); //关闭文件测试链接数 close(fd); stat("abc", &buf); printf("3. link =%d \n", buf.st_nlink); //创建硬链接,测试链接数 if(link("abc", "abc1")) printf("link abc fail\n"); stat("abc", &buf); printf("4. link =%d \n", buf.st_nlink); //删除abc1,测试链接数 if(unlink("abc1") == 0) printf("\tdelete abc1\n"); stat("abc", &buf); printf("5. link =%d \n", buf.st_nlink); //重复步骤2 fd = open("abc", O_RDONLY); stat("abc", &buf); printf("2. link =%d \n", buf.st_nlink); //删除abc if(unlink("abc") == 0) printf("\tdelete abc\n"); fstat(fd, &buf); printf("7. link =%d \n", buf.st_nlink); close(fd); return 0; }
为保证有abc,先执行: touch abc, 然后编译运行:
1. link =1 2. link =1 3. link =1 4. link =2 delete abc1 5. link =1 2. link =1 delete abc 7. link =0
相关文章推荐
- linux中使用php-mysql出错
- linux小白日记
- linux内核移植和跟文件系统制作
- linux下快捷键 推荐(大一学生) :终端+gdb (有重复,前面部分是自己觉得重要的摘录)
- 跟踪分析Linux内核的启动过程
- CentOS 6.5编译安装LAMP分离环境的搭建
- Linux 环境变量PATH设置
- Linux下定时任务配置-crontab
- 亚马逊云主机aws linux putty 登录报错 server refused our key解决
- linux下制作u盘启动盘的方法
- centos更改默认语言
- Linux之mount命令详解
- centos 6.6编译安装mysql 5.6
- Linux 批量建立信任关系,实现ssh无密码登陆的脚本
- VirtualBox内Linux系统与Windows共享文件夹
- linux常用vi编辑器命令行
- Linux 搭建 discuz 论坛
- Linux Centos 6.6搭建SFTP服务器
- linux中的定时任务--cron任务
- Linux下 MySQL Show命令的使用