Linux上C中的递归文件删除

时间:2010-09-30 18:18:36

标签: c unix

我有一个C程序,在程序的某个点上有这个:

system(“rm -rf foo”);

foo是一个目录。我决定,而不是调用系统,最好在代码中执行递归删除。我假设一段代码很容易找到。傻我。无论如何,我最后写了这个:

#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;

}

这似乎有效,但我太害怕在生产中实际使用它。我确定我做错了什么。有没有人知道一个C库做递归删除我错过了,或者有人能指出我犯的任何错误?

感谢。

4 个答案:

答案 0 :(得分:13)

POSIX有一个名为ftw(3)(文件树步行)的函数

  

遍历目录dirpath下的目录树,并为树中的每个条目调用fn()一次。

答案 1 :(得分:3)

感到害怕被吓死,在这种情况下,这是一种健康的态度。

我没有图书馆建议你在哪种情况下有两个选择:

1)详尽地“运行”此代码 a)不在机器上;在纸上,用铅笔。获取现有目录树,列出所有元素并通过每个步骤运行程序,验证它是否正常工作 b)编译代码,但用执行printf的行替换所有删除调用 - 验证它是否应该执行的操作
c)重新插入删除调用并运行

2)使用您的原始方法(call system())

答案 2 :(得分:2)

我建议您采取一项额外的预防措施。

几乎总是在删除多个文件和/或目录时,最好在执行任何可能破坏此目录之外的数据之前将chroot()放入dir中。

答案 3 :(得分:1)

我认为你需要在recursiveDelete()之前调用closedir()(因为你不想/ /当你进入它们时需要打开所有目录。在调用remove()之前还要关闭/(因为remove()将可能会在打开的目录上给出一个错误。你应该仔细检查一次,以确保readdir()没有拾取'..'。同时要警惕链接目录,你可能不想递归到目录那里是 符号或硬链接。