Проверка наличия каталога в Unix (системный вызов)

Я не могу найти решение моей проблемы в интернете.

Я хотел бы вызвать функцию в Unix, передать путь к каталогу и узнать, существует ли она. opendir() возвращает ошибку, если каталог не существует, но моя цель состоит не в том, чтобы открыть, проверить ошибку, закрыть ее, если нет ошибки, а просто проверить, является ли файл каталогом или нет.

есть ли удобный способ сделать это, пожалуйста?

8 ответов


в системах POSIX есть две соответствующие функции:stat() и lstat(). Они используются, чтобы узнать, относится ли путь к фактическому объекту, к которому у вас есть разрешение на доступ, и если да, то возвращаемые данные говорят вам, какой это тип объекта. Разница между stat() и lstat() это если имя, которое вы даете, является символической ссылкой,stat() следует за символической ссылкой (или ссылками, если они связаны вместе) и сообщает об объекте в конце цепочки ссылки, тогда как lstat() отчеты о самой символической ссылке.

#include <sys/stat.h>

struct stat sb;

if (stat(pathname, &sb) == 0 && S_ISDIR(sb.st_mode))
{
    ...it is a directory...
}

если функция указывает, что она была успешной, вы используете макрос S_ISDIR () из <sys/stat.h> определить, является ли файл на самом деле является каталогом.

вы также можете проверить другие типы файлов, используя другие S_IS* макросы:

  • S_ISDIR - каталог
  • S_ISREG - обычным файлом
  • S_ISCHR - характер устройство
  • S_ISBLK - блочное устройство
  • S_ISFIFO - ФИФО
  • S_ISLNK - символическая ссылка
  • S_ISSOCK - socket

(некоторые системы также предоставляют несколько других типов файлов;S_ISDOOR доступен на Solaris, например.)


вы можете использовать stat системный вызов, передав его имя каталога в качестве первого аргумента. Если каталог существует 0 возвращается else -1 возвращается, и errno будет установлено в ENOENT

EDIT:

если возвращаемое значение 0 вам понадобится дополнительная проверка, чтобы убедиться, что аргумент на самом деле является каталогом, а не файлом/symlink/char special file/blk special file/FIFO file. Вы можете использовать


можно использовать test -d


Если вы говорите о из оболочки, есть хороший ответ так здесь. подводя итог этому ответу:

if [ -d "$DIRECTORY" ]; then
    # Control will enter here if $DIRECTORY exists
fi

Если вы говорите изнутри программы C, вы можете использовать stat():

{
    struct stat st;
    if(stat("/tmp",&st) == 0)
        printf(" /tmp is present\n");
}

Если вас действительно не волнует тип этого объекта файловой системы, access (name, F_OK) проверяет наличие чего-либо с этим именем. Если вам нужно убедиться, что это каталог, используйте stat() и проверьте тип с помощью макроса S_ISDIR ().


проверена и работает нормально:

int file_exist (char *filename)
{
    char s[200];
    sprintf(s, "test -e %s", filename);
    if (system(s) == 0){
        return 1;
    }else{
        return 0;
    }
}

другим простым способом было бы:

int check(unsigned const char type) {
    if(type == DT_REG)
        return 1;
    if(type == DT_DIR)
        return 0;
    return -1;
}

затем вы можете передать struct dirent* d_type объекта в Регистрация


Я думаю, что функция stat может делать то, что вы хотите (я не тестирую ее для каталогов). В C++ вы также можете использовать библиотеку boost::filesystem.