Как рекурсивно пройтись по каталогу и распечатать все файлы на C?

Я пытаюсь рекурсивно пройтись по каталогу и распечатать все файлы.

Когда я пытаюсь сделать это с помощью приведенного ниже кода, например, я вызываю функцию с помощью 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, но я не уверен.

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(".", "."); рекурсивно пройтись по каталогу и распечатать все файлы.

Вдохновлен этим ответом.

Другие вопросы по тегам