Как правильно использовать функцию stat() для проверки того, является ли DIRENT каталогом или файлом?

StackOverflow https://stackoverflow.com/questions/1542763

  •  20-09-2019
  •  | 
  •  

Вопрос

У меня возникли проблемы со строкой if(S_IFDIR(stbuf.st_mode))'.Это правильный способ проверить каталог для рекурсии?На данный момент функция, кажется, делает все правильно в течение 1 или 2 циклов, а затем дает сбой и возникает ошибка сегментации.

Я попробовал следующее и, возможно, больше в качестве условия.

S_ISDIR(st_mode)
((st_mode & ST_IFMT) == S_IFDIR)
S_IFDIR(stbuf.st_mode)

Я включил всю функцию, потому что опасаюсь, что проблема может быть в другом месте.

void getFolderContents(char *source, int temp){
    struct stat stbuf;
    int isDir;
    dirPnt = opendir(source);
    if(dirPnt != NULL){
        while(entry = readdir(dirPnt)){
            char *c = entry->d_name;
            if(strcmp(entry->d_name, cwd) == 0 || strcmp(entry->d_name, parent) == 0){
            }
            else{
                stat(entry->d_name, &stbuf);
                printf("%i %i ", S_IFMT, stbuf.st_mode);
                if(S_IFDIR(stbuf.st_mode)){            //Test DIR or file
                printf("DIR: %s\n", entry->d_name);
                getFolderContents(entry->d_name, 0);
            }
            printf("FILE: %s\n", entry->d_name);
        }
    }
    closedir(dirPnt);
}
Это было полезно?

Решение

Да, это правильно.Но поскольку вы никогда не переходите в каталог, вы его не найдете.

Рассмотрим следующую иерархию каталогов:

 a
 |
 +- b
 |  |
 |  +- c
 ...

Ваш код просканирует свой текущий каталог и найдет «a».Он определит, что это каталог, рекурсивно вызовет себя и откроет «a» для чтения.Это работает.При этом сканировании будет найден каталог с именем «b», но попытка открыть его, используя только имя записи, не удастся, поскольку теперь путь — «a/b».

Я рекомендую перейти в каталог (с помощью чдир()), прежде чем открыть его.Это означает, что вы можете просто opendir(".").Сохраните старый путь и chdir() out снова, когда рекурсия этого уровня будет завершена (не раньше, чем будет выполнен рекурсивный вызов для перехода глубже).

Другие советы

Где определяется запись?это локальная переменная?Я не понимаю, почему это может привести к сбою, но, возможно, вам следует сделать это локальной переменной.Один из примеров, когда он вас укусит, находится здесь:

                    if(S_IFDIR(stbuf.st_mode)){            //Test DIR or file
                            printf("DIR: %s\n", entry->d_name);
                            getFolderContents(entry->d_name, 0);
                    }
                    printf("FILE: %s\n", entry->d_name);

printf напечатает неправильное имя, поэтому вам, вероятно, следует добавить сюда другое.

То же самое и с dirpnt.Когда вы выходите из GetFoldContents внутри цикла, вы в конечном итоге звоните ReadDir в закрытом указателе, который должен вытащить вас из петли.

Но, как сказал Бахбар:Вы не можете рекурсивно хранить временную переменную в глобальной переменной.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top