Linux下C语言中的递归文件删除
我有一个C程序,在程序的某一点上有: 系统(“rm-rf foo”) 其中foo是一个目录。我决定,与其调用系统,不如在代码中正确执行递归删除。我认为这样做的代码很容易找到。我真傻。总之,我最后写了这样一篇文章:Linux下C语言中的递归文件删除,c,unix,C,Unix,我有一个C程序,在程序的某一点上有: 系统(“rm-rf foo”) 其中foo是一个目录。我决定,与其调用系统,不如在代码中正确执行递归删除。我认为这样做的代码很容易找到。我真傻。总之,我最后写了这样一篇文章: #include <stdio.h> #include <sys/stat.h> #include <dirent.h> #include <libgen.h> int recursiveDelete(char* dirname) {
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>
#include <libgen.h>
int recursiveDelete(char* dirname) {
DIR *dp;
struct dirent *ep;
char abs_filename[FILENAME_MAX];
dp = opendir (dirname);
if (dp != NULL)
{
while (ep = readdir (dp)) {
struct stat stFileInfo;
snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname, ep->d_name);
if (lstat(abs_filename, &stFileInfo) < 0)
perror ( abs_filename );
if(S_ISDIR(stFileInfo.st_mode)) {
if(strcmp(ep->d_name, ".") &&
strcmp(ep->d_name, "..")) {
printf("%s directory\n",abs_filename);
recursiveDelete(abs_filename);
}
} else {
printf("%s file\n",abs_filename);
remove(abs_filename);
}
}
(void) closedir (dp);
}
else
perror ("Couldn't open the directory");
remove(dirname);
return 0;
}
#包括
#包括
#包括
#包括
int递归删除(char*dirname){
DIR*dp;
结构方向*ep;
char abs_filename[filename_MAX];
dp=opendir(dirname);
如果(dp!=NULL)
{
while(ep=readdir(dp)){
struct stat stFileInfo;
snprintf(abs\u文件名,文件名\u MAX,“%s/%s”,目录名,ep->d\u名称);
if(lstat(abs_文件名和stFileInfo)<0)
perror(abs_文件名);
if(S_ISDIR(stFileInfo.st_模式)){
如果(strcmp(ep->d_name,“.”&)
strcmp(ep->d_名称,“…”){
printf(“%s目录\n”,abs\u文件名);
递归删除(abs_文件名);
}
}否则{
printf(“%s文件\n”,abs\u文件名);
删除(abs_文件名);
}
}
(无效)closedir(dp);
}
其他的
perror(“无法打开目录”);
删除(dirname);
返回0;
}
这似乎有效,但我太害怕在生产中实际使用它。我肯定我做错了什么。有没有人知道我错过了一个C库来执行递归删除,或者有人能指出我犯的任何错误
谢谢。被吓得要死,在这种情况下,这是一种健康的态度 我没有图书馆可供建议,在这种情况下,您有两种选择: 1) 彻底地“运行”此代码
a) 不是在机器上;在纸上,用铅笔。获取现有目录树,列出所有元素,并在每个步骤中运行程序,验证它是否有效
b) 编译代码,但将所有删除调用替换为执行printf的行-验证它是否执行了它应该执行的操作
c) 重新插入删除调用并运行
2) 使用原始方法(call system())POSIX有一个名为(文件树漫游)的函数 遍历位于目录dirpath下的目录树,并为树中的每个条目调用fn()
我认为您需要在recursiveDelete()之前调用closedir()(因为您不希望/需要在进入目录时打开所有目录。另外,在调用remove()之前调用closedir(),因为remove()可能会在打开的目录上出错。您应该仔细执行一次,以确保readdir()不拾取“..”。还要注意链接目录,您可能不希望递归到
符号链接或硬链接。我建议您采取另外一种预防措施
几乎总是在删除多个文件和/或目录时,最好使用chroot()在执行任何可能破坏此目录外数据的操作之前,请将其输入目录。实际上,当您将某些内容传递给shell时,它将进入操作系统,并以机器代码运行。Unix内核经过了极大的优化,因此,即使您完全按照Unix内核中的编码方式对其进行编码,您可能也只能看到5-10%的性能Ncrese。传递给shell太简单和方便了。请参阅[Delete folder with items]()和。有趣的是:
remove()
的POSIX规范在非目录(文件、符号链接等)上说了unlink()
,在目录上说了rmdir()
。您应该检查remove()
有效-如果没有,则报告。您应该看看如果函数的参数不是目录,会发生什么情况-它会抱怨无法打开目录(但没有说明是哪一个;这也很糟糕),然后将其删除(或尝试删除).Yup.POSIX来拯救。它可能更安全、更快,并且捕捉到在手动导线测量的正常操作过程中通常不会出现的小错误。此外,还有新的FTW功能-具有稍微不同的界面。nftw
是您所追求的-请参阅。