【问题标题】:How to recursively walk through a directory and print all files in C?如何递归遍历目录并打印C中的所有文件?
【发布时间】:2017-10-17 15:17:55
【问题描述】:

我正在尝试递归遍历一个目录并打印出所有文件。

当我尝试使用下面的代码执行此操作时,例如,我使用 sprint(".", ".") 调用该函数,我得到一堆点的输出。

当我减少允许的打开进程数量 (ulimit -n 20) 时,我得到 17 个点。不过我不明白,因为我认为 readdir() 和 opendir() 不会创建新进程。这是我的代码:

void sprint(char *filename, char * dirToOpen) {
    DIR *directory = opendir(dirToOpen);
    struct dirent *entry;
    struct stat s;
    char pathname[1024];
    if (directory) { /*if it's a directory*/
       while ((entry = readdir(directory)) != NULL) { /*while there are more entries to read*/
          if(strcmp(entry->d_name, filename) == 0) /*if entry name corresponds to filename, print it*/
             printf("%s\n", filename);
          sprintf(pathname, "./%s", entry->d_name); /*makes pathname*/
          if (lstat(pathname, &s) == 0 && S_ISDIR(s.st_mode)) { /*if the file is a directory*/
             if(strcmp(entry->d_name, "..") != 0 && strcmp(entry->d_name, ".") != 0) /*if the directory isn't . or ..*/
                sprint(filename, entry->d_name);
          }
       }
       closedir(directory);
    }
 }

此外,它不会到达其余文件,因为它只打印点,而不是完整的文件名。我认为它在我最后一个 if 循环中的某个地方,但我不确定。

【问题讨论】:

  • 我假设这是一个 POSIX 系统(Linux / BSD)?你考虑过the nftw function吗?

标签: c unix recursion directory


【解决方案1】:

这是一个递归代码:

void sprint(char *filename, char * dirToOpen, int level = 0)
{
    DIR *dir;
    struct dirent *entry;
    struct stat s;

    if (!(dir = opendir(dirToOpen)))
        return;
    if (!(entry = readdir(dir)))
        return;

    do
    {
        if(lstat(dirToOpen, &s) == 0 && S_ISDIR(s.st_mode)) /*if it's a directory*/
        {
            char path[1024];
            int len = snprintf(path, sizeof(path)-1, "%s/%s", dirToOpen, entry->d_name); /*makes pathname*/
            path[len] = 0;
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) /*if the directory isn't . or ..*/
                continue;
            printf("%*s[%s]\n", level * 2, "", entry->d_name);
            sprint(filename ,path, level + 1);
        }
        else
        {
            if(strcmp(entry->d_name, filename) == 0 || strcmp(filename, ".") == 0) /*if entry name corresponds to filename, print it*/
             printf("%*s- %s\n", 2, "", entry->d_name);
        }
    } while (entry = readdir(dir)); /*while there are more entries to read*/
    closedir(dir);
}

使用sprint(".", "."); 调用它以递归地遍历目录并打印出所有文件。

灵感来自this 的回答。

【讨论】:

  • 嗨,我应该分享我在 unix 上,所以没有 d_type,但我可以使用 lstat 代替。谢谢!
  • @AleksVetushko 我已经更新了用lstat 替换d_type 的答案。这对你有用吗?
  • 请注意,void sprint(char *filename, char * dirToOpen, int level = 0) 中的 level 等默认参数是 C++ 功能,不是标准 C 的一部分。
  • @JonathanLeffler 对。感谢您的煽动。
猜你喜欢
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 2014-08-27
  • 1970-01-01
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
  • 2021-05-04
相关资源
最近更新 更多