一、函数声明
#include <unistd.h>
int unlink(const char *pathname);
#include <fcntl.h> /* Definition of AT_* constants */
#include <unistd.h>
int unlinkat(int dirfd, const char *pathname, int flags);
#include <stdio.h>
int remove(const char *pathname);
- unlink 只可以删除文件。
- unlinkat 可以删除文件(默认)或文件夹(需要设置 flags 为 AT_REMOVEDIR)。
- remove 可以删除文件,或者文件夹。【可以认为 remove 底层是 unlinkat 一样的实现,只不过不需要针对是文件夹时,指定参数 AT_REMOVEDIR】
二、实例
2.1、基本使用(删除文件,与目录)
2.1.1、unlink (结果,文件删除成功,无法删除目录)
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **args)
{
if (unlink("test") < 0) {
perror("unlink file test with fail");
exit(-1);
}
return 0;
}
hotice0@ubuntu:~/Documents/Unix_Program$ touch test
hotice0@ubuntu:~/Documents/Unix_Program$ ./main
hotice0@ubuntu:~/Documents/Unix_Program$ mkdir test
hotice0@ubuntu:~/Documents/Unix_Program$ ./main
unlink file test with fail: Is a directory
2.1.2、跟踪 rm -r (其使用的是 unlinkat 系统调用)
跟踪命令 strace rm -r test
,结果如下
...
unlinkat(AT_FDCWD, "test", AT_REMOVEDIR) = 0
...
2.1.3、unlinkat (带 AT_REMOVEDIR 时,能删除文件夹,不带时能删除文件)
#define __USE_ATFILE
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **args)
{
if (unlinkat(AT_FDCWD, "test", AT_REMOVEDIR) < 0) {
perror("unlinkat file test with fail");
exit(-1);
}
return 0;
}
hotice0@ubuntu:~/Documents/Unix_Program$ mkdir test
hotice0@ubuntu:~/Documents/Unix_Program$ ./main
hotice0@ubuntu:~/Documents/Unix_Program$ touch test
hotice0@ubuntu:~/Documents/Unix_Program$ ./main
unlinkat file test with fail: Not a directory
2.1.4、remove(可以删除文件,或者文件夹)
// 简单的实例
#include <stdio.h>
int main(int argc, char **args)
{
remove("test");
return 0;
}
2.2、创建临时文件
即,首先通过 open 打开并创建文件,随后调用 unlink 减少文件计数。但是由于该文件被程序打开,所以文件不会被立即删除,而是进程退出时,内核会判断没有其他进程打开该文件,并且文件链接数为 0,才会真正的删除文件。
下面是用于验证的程序
#define __USE_ATFILE
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF_SIZE 1024
int main(int argc, char **args)
{
int fd;
char buf[BUF_SIZE] = {0};
fd = open("test", O_CREAT|O_RDWR, S_IRWXU);
if (fd < 0) {
perror("open with fail");
exit(-1);
}
printf("file created\n");
sleep(5);
if (unlink("test") < 0) {
perror("unlink file test with fail");
close(fd);
exit(-1);
}
printf("unlinked\n");
sleep(5);
if (write(fd, "hotice0", strlen("hotice0")) < 0) {
perror("write with fail");
close(fd);
exit(-1);
}
if (lseek(fd, 0, SEEK_SET) < 0) {
perror("lseek with fail");
close(fd);
exit(-1);
}
if (read(fd, buf, BUF_SIZE) < 0) {
perror("read with fail");
close(fd);
exit(-1);
}
printf("read from file test: %s\n", buf);
close(fd);
printf("closed file\n");
return 0;
}
这个程序很简答,首先创建 test 文件,然后 sleep 5s,再调用 unlink 删除该文件,再 sleep 5s,再向文件写入,内容并且读出,然后 close 文件。
// A terminal
./main
file created
unlinked
read from file test: hotice0
closed file
// B terminal
hotice0@ubuntu:~/Documents/Unix_Program$ ll test // 这一步是在open test文件之后,文件就存在了
-rwx------ 1 hotice0 hotice0 0 Aug 8 00:34 test*
hotice0@ubuntu:~/Documents/Unix_Program$ ll test // 这一步是在unlink调用之后,文件在该目录中无法找到了
ls: cannot access 'test': No such file or directory
三、总结
- unlink 默认,只能删除文件的链接。
- unlinkat可以通过flag参数,是否是 AT_REMOVEDIR,控制删除文件还是文件夹。
(所以可以通过 open 打开文件后,通过 stat 获取文件类型,根据类型决定是否使用AT_REMOVEDIR)。 - remove 函数作用其实和 unlink 和 unlinkat 作用是一样的,但是可以删除文件和文件夹,不需要指定类型(是文件还是文件夹)。
转载:Linux unlink/unlinkat/remove 函数_HotIce0的博客-CSDN博客_unlinkat
(SAW:Game Over!)