stat использует S_ISDIR Не всегда работает - PullRequest
0 голосов
/ 05 марта 2020

Я заметил что-то странное в выводе моей функции (в c). Эта функция обнаруживает в каталоге, является ли элемент файлом или подкаталогом.

// i cant detected properly if an element is a file or a dir 
int RecursiveSearch(char *Dir){
    DIR *Directory;
    //DIR *SubDirectory;
    struct dirent *entry;
    struct stat filestat;

    printf("I am Reading %s Directory\n", Dir);

    Directory = opendir(Dir);
    if(Directory == NULL)
    {
        perror("Unable to read directory.. i'm leaving\n");
        return(1); // leave
    }

    /* Read directory entries */
    while( (entry=readdir(Directory)) )
    {
        stat(entry->d_name,&filestat);
        if( S_ISDIR(filestat.st_mode) ){
            printf("%4s: %s\n","Dir",entry->d_name);
            if (strstr(entry->d_name, ".") == NULL && strstr(entry->d_name, "..") == NULL ) // to not infinit loop
            {
                // Recursion
                printf("\n*Entering a subDirectory*\n");
                RecursiveSearch(entry->d_name);
                printf("\n*Leaving a subDirectory*\n");
            }


        }
        else
            printf("%4s: %s\n","File",entry->d_name);
    }
    closedir(Directory);

    return(0);
}

Я вызываю его в основном таким образом, чтобы проверить его RecursiveSearch("./Directories");

И это мой вывод enter image description here

Моя проблема находится в разделе «Запуск рекурсивного исследования ..»

Как видите, SubDir не является файлом. Я не вижу, что я сделал неправильно в функции.

Если вам нужны какие-либо дополнительные разъяснения, пожалуйста, спросите.

РЕДАКТИРОВАТЬ:

int RecursiveSearch(char *Dir){
    DIR *Directory;
    struct dirent *entry;
    struct stat filestat;

    printf("I am Reading %s Directory\n", Dir);

    Directory = opendir(Dir);
    if(Directory == NULL)
    {
        perror("Unable to read directory.. i'm leaving\n");
        return(1); // leave
    }

    /* Read directory entries */
    while( (entry=readdir(Directory)) )
    {
        char fullname[100];
        sprintf(fullname, "%s/%s",Dir,entry->d_name);
        stat(fullname,&filestat);
        if( S_ISDIR(filestat.st_mode) ){
            printf("%4s: %s\n","Dir",fullname);
            if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0 ) // to not infinite loop
            {
                // Recursion
                printf("\n*Entering a subDirectory*\n");
                RecursiveSearch(fullname);
                printf("\n*Leaving a subDirectory*\n");
            }
        }
        else
            printf("%4s: %s\n","File",fullname);
    }
    closedir(Directory);

    return(0);
}

1 Ответ

2 голосов
/ 05 марта 2020

entry->d_name это просто имя, оно не имеет префикса каталога. Он интерпретируется относительно рабочего каталога процесса, а не текущего каталога в рекурсии функции.

При вызове других функций, в том числе рекурсии, вам необходимо добавлять префикс имени к имени каталога.

Кроме того, вам нужно использовать strcmp(), чтобы сравнить имя с . и ... Использование strstr() предотвращает повторное обращение в каталоги, в которых в именах есть ..

int RecursiveSearch(char *Dir){
    DIR *Directory;
    struct dirent *entry;
    struct stat filestat;

    printf("I am Reading %s Directory\n", Dir);

    Directory = opendir(Dir);
    if(Directory == NULL)
    {
        perror("Unable to read directory.. i'm leaving\n");
        return(1); // leave
    }

    /* Read directory entries */
    while( (entry=readdir(Directory)) )
    {
        char fullname[MAXPATH];
        sprintf(fullname, "%s/%s", Dir, entry->d_name);
        stat(fullname,&filestat);
        if( S_ISDIR(filestat.st_mode) ){
            printf("%4s: %s\n","Dir",fullname);
            if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0 ) // to not infinite loop
            {
                // Recursion
                printf("\n*Entering a subDirectory*\n");
                RecursiveSearch(fullname);
                printf("\n*Leaving a subDirectory*\n");
            }
        }
        else
            printf("%4s: %s\n","File",fullname);
    }
    closedir(Directory);

    return(0);
}
...