Linux unlink函数和删除文件的操作方法
作者:LU_ZHAO 发布时间:2023-10-05 06:27:51
1. unlink函数
对于硬链接来说,unlink 用来删除目录项,并把 inode 引用计数减 1,这两步也是一个原子过程。直到 inode 引用计数为 0,才会真正删除文件。
对于软链接来说,unlink 直接删除软链接,而不影响软链接指向的文件。
函数原型:
int unlink(const char *pathname);
参数说明:
pathname:指定要移除的链接文件
返回值说明:
成功返回0;失败则返回-1,同时设置errno为相应值
2. 实验代码—myunlink
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]){
//为一个已经存在的文件创建目录项(硬链接)
if(link(argv[1], argv[2]) == -1){
perror("link error");
exit(1);
}
//删除之前的文件目录项
if(unlink(argv[1]) == -1){
perror("unlink error");
exit(1);
}
return 0;
}
当我们执行./myunlink hellotest命令完后,会删除 hellotest,同时 inode 引用计数减 1。
3. 删除文件
不用说,相信大家都用过rm -rf命令吧。
现在我们再来思考一下,以前我们通过rm命令删除文件时你有没有质疑过,文件真的被删除掉了吗?
如果真的删除的了话,那么操作系统又是怎么把文件删除掉的?
操作系统在设计的时候是通过把文件的inode索引号与磁盘中的block块建立了关联,这样我们通过文件找到block块的位置,也就看到了文件的数据了。
在删除文件时,是由系统的2个变量来控制的一个是i_link,表示文件的硬链接数量,另一个是i_count,表示文件的引用计数,文件删除的必需条件就是i_link = 0和i_count = 0。
在磁盘中的文件只要把i_link = 0(硬链接数干掉)就可以把文件删除了,如果这个文件在程序中被打开,我们还需要把运行的程序干掉 i_count = 0,这样才能达到删除文件的目的。
4. linux下删除文件的大概过程
linux下文件删除过程大概如图:
图1-linux下文件删除的大概过程
当前磁盘中的/test/file目录下有一个test文件(i_link = 1),还有一个硬链接文件hard_link指向test文件(i_link = 1),且./test进程又打开了test文件(i_count = 1),如果要删除test.txt文件,必须把./test进程干掉(i_count = 0),然后删除hard_link硬链接文件和/test/file目录下的test.txt文件(也就是让i_link = 0)。
也就是说linux下是通过link的数量来控制文件删除的,当一个文件的link = 0时,这个文件才会被删除。一般一个文件有2个link计数器,一个是i_link和i_count。
i_count是当前进程打开文件的引用计数,i_link是文件链接的数量,可以把i_count理解为内存中文件的计数器,而i_link是磁盘中的计数器。对于rm命令来说实际就是设置磁盘中文件的i_link计数为0。如果一个文件被进程所使用,而用户又执行了rm命令把文件删除掉了,此时程序还能正常执行,依旧能从文件中读取正确的数据,这是因为rm命令只是把i_link设置为 0(是将文件到inode的关联断开,并没有删除掉inode与磁盘中的block数据块,此时停止进程,被删除的数据可以找回来,如果进程正在写入数据,那么磁盘的block块的数据会被进程写入的数据覆盖掉,原先的数据就恢复不了了)。
而进程仍然在引用该文件i_count = 1,执行rm命令系统并不会真正的删除该文件,如果要删除该文件必须让进程解除对该文件的引用计数,也就是把进程干掉,这样文件才会被真正的删除掉。
即便如此,文件真的被删除了吗?前面我们说过文件的数据是存储在磁盘上block块中,当我们要查找文件当中的数据时并不是直接找到磁盘上的block块,因为磁盘上的block块实在是太多了,你怎么就知道你的数据存储在哪个block块中?
假设你一不小心把非常重要的数据删除掉了,这将意味着你的数据就永远也找不回来了,从而造成无法挽回的损失了,由此可见数据的重要性,因此操作系统不会轻易把数据从磁盘中真正的删除掉。
看到这里,相信你已经明白了,实际上你所谓的右键删除操作只是把文件的inode索引号与磁盘中的block的关联断开了而已,但文件的数据并没有真正的被删除掉。如果你想真的删除数据的话,要么把磁盘格式化,要么把原先的数据删除掉,然后写入新的数据覆盖掉,当然,你也可以选择格式化和数据覆盖双重保险,这个时候你的数据想要恢复基本上是非常困难的,即便可以顶多只能恢复一部分数据了吧。
如果你真的一不小心删除了很重要的数据的话,这个时候赶紧恢复数据,其他的任何多余的操作尽量不要做,这样在数据恢复过程中才能尽量减少数据丢失。
5. myunlink2.c程序
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*
unlink函数是删除一个dentry
*/
int main(void){
int fd;
char *p = "test of unlink\n";
char *p2 = "after write something.\n";
//当进程打开temp.txt文件时,引用计数会+1
fd = open("temp.txt", O_RDWR|O_CREAT|O_TRUNC, 0644);
if(fd < 0){
perror("open temp error");
exit(1);
}
//具备了被释放的条件
int ret = unlink("temp.txt");
if(ret < 0){
perror("unlink error");
exit(1);
}
//向temp.txt文件写入第一个字符串,通过返回值判断写操作是否成功
ret = write(fd, p, strlen(p));
if (ret == -1) {
perror("-----write error");
}
printf("hi! I'm printf\n");
//向temp.txt文件写入第二个字符串,通过返回值判断写操作是否成功
ret = write(fd, p2, strlen(p2));
if (ret == -1) {
perror("-----write error");
}
printf("Enter anykey continue\n");
getchar();
//当close关闭fd的时候,进程对文件的引用计数就会-1,断开进程与文件的关联关系
close(fd);
return 0;
}
程序运行结果:
程序的运行结果和我们所预料的一样,当程序运行的时候,调用open函数创建并打开了temp.txt文件,此时进程对temp文件的引用计数i_count会加1,同时temp文件本身也会有一个i_link链接计数也会加1。
当调用了unlink函数删除temp文件时,只是把i_link链接计数减1,而进程的i_count计数还是1,并没有断开与temp文件的关联关系,因此进程可以调用write函数往temp文件里面写数据,自然也就能成功了。当程序运行结束后,调用close关闭对temp文件的引用,此时temp文件就会 * 作系统删除掉。
6. 总结
在不了解文件系统原理的情况下,通常我们会认为数据已经删除掉,其实不然,磁盘上的文件数据还在,只是把dentry目录和磁盘上的数据的联系断开,我们找不到数据肯定会认为删掉了,但是只要我们想办法让数据和dentry目录之间重新建立连接,就可以让删除的数据恢复。
因此我们删除文件,从某种意义上说,只是让文件具备了被释放的条件,至于什么时候释放这取决于操作系统。
对于unlink函数来说,清除文件时,如果文件的硬链接数到0了,没有dentry对应,但该文件仍不会马上被释放。要等到所有打开该文件的进程关闭该文件,系统才会挑时间将该文件释放掉。
7. 不要随便使用rm命令
相信看到这里,你应该知道了,数据对于计算机的重要性了,因为一旦某些至关重要的数据删除了,那就真的永远没了,这也是操作系统为什么不直接将数据从磁盘中删除的原因。但也不要因为这样,你就可以肆无忌惮的使用rm命令了,因为有时候数据删除了,并不能百分百的恢复回来。
总结
以上所述是小编给大家介绍的Linux unlink函数和删除文件的操作方法,希望对大家有所帮助
来源:https://blog.csdn.net/LU_ZHAO/article/details/104335284


猜你喜欢
- 在Windows7面世之后,其华丽的界面、任务栏预览、快速跳转等一系列新特性令人爱不释手。而酷我音乐盒作为最优秀的网络音乐播放器,已经率先实
- 一、搭建1、准备htpasswd.txt文件该文件内容包含上传包至仓库时验证的用户名和密码pip install htpasswdhtpas
- 怎样更改GoDaddy主机的FTP账户密码呢?如果有必要,你可以使用Hosting Control Center来更改你的托管帐户的密码。这
- 北京时间12月3日消息,据国外媒体报道,正在与美国最大的分类信息网站Craigslist对簿公堂的eBay周三表示,为从分类列表中获取更多营
- 中国互联网协会公布的2008年一季度中国反垃圾邮件调查结果显示,商业广告类是侵扰用户的垃圾邮件的主要来源;在用户最讨厌的垃圾邮件中,病毒型垃
- 装了ubuntu好长一段时间了,都没去用,国庆的时候折腾了下,配置了一些基本的开发环境,一上手就感觉喜欢上了ubuntu,说不上为什么。为了
- 一、firewalld 守护进程firewall-cmd命令需要firewalld进程处于运行状态。我们可以使用systemctl stat
- 避免使用Javascript作URL链接。有些时候,为了让页面上的URL链接变的更加美观,或者为了后台操作的便利,有些网站的URL是用形如下
- 数据显示,虽然经济危机对于互联网行业带来了很大的影响,但是08年网络广告行业还是有180多亿的规模,分析还指出,09年还会有20%的增长率。
- 做seo的人,接到一个新的网站,第一步肯定要先诊断一个网站,然后,才能针对网站中存在的问题进行分析,再制定相关的优化方案。再进行优化。所以,
- 应用实例我校1#学生公寓,PC拥有数量大约1000台。采用DHCP分配IP地址,拥有4个C类地址,实际可用地址数约1000个。由于楼内经常存
- 现在网赚其实已经很流行了,但是多数学生只了解其表面,根本不懂其真实内容,记得原来我高中的时候看到有个网站上出现网赚这个词,是发展下线那种的,
- Google自从发布了Google分析(Google Analytics)中的AdSense工具后,只要将将AdSense帐号和Analyt
- “关于《剑三》的联合运营,金山的确在和九城协商,不过具体上线还要看双方情况,2010年应该会有相关合作机会。”11月26日,金山网游COO湛
- 众所周知,QQ空间的人气很高,那作为站长的我们能否利用QQ的高人气呢?答案是肯定的!虽然QQ空间带来的反链效果很差,但带来的流量却相当可观!
- 一、目的本地写好一个Flask应用,用Docker封装,上传至自己的服务器,完成部署。流程图:二、实验环境本地:Windows10 1909
- 写下这篇文章之前,我想先说说我自己,我,玉龙,建站经验8年,在K666时代开始泡,chinaz泡过,落伍泡过,cnzz泡过,XXSKY的时候
- SEOer每天都在考量很多指标以维护目前的成绩,其中有几点是大可不必太操心的:越高的Pagerank越好? 在SEO这个行业刚刚出现的时候,
- B2B电子商务网站优化已经成为B2B网站网络营销策略中最基本的内容,一个整体优化状况不好的B2B电子商务平台,不仅用户发布的供求信息难为潜在
- 曾引发网民热议的“网易老总丁磊养猪”一事,又有新消息!21日,记者独家从相关渠道获悉,网易将先期投资