Проверка, существует ли каталог в Unix (системный вызов) - PullRequest
49 голосов
/ 30 сентября 2010

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

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

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

Ответы [ 8 ]

105 голосов
/ 30 сентября 2010

В системах POSIX есть две соответствующие функции: stat () и lstat () .Они используются, чтобы выяснить, относится ли путь к реальному объекту, к которому у вас есть права доступа, и если да, возвращенные данные сообщают вам, какой это тип объекта.Разница между stat() и lstat() заключается в том, что если имя, которое вы даете, является символической ссылкой, stat() следует за символической ссылкой (или ссылками, если они связаны друг с другом) и сообщает об объекте в конце цепочкиlinks, тогда как 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 - FIFO
  • S_ISLNK - символьноессылка
  • S_ISSOCK - сокет

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

5 голосов
/ 30 сентября 2010

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

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

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

3 голосов
/ 30 сентября 2010

Вы можете использовать test -d

3 голосов
/ 30 сентября 2010

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

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");
}
1 голос
/ 22 августа 2018

Другой простой способ будет:

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

Затем можно передать struct dirent * d_type объекта в check функцию.

Если проверка возвращает 1, то этот путь указывает на обычный файл.

Если проверка возвращает 0, то этот путь указывает на каталог.

В противном случае это не файл или каталог (это может быть блочное устройство / символическая ссылка и т. Д.)

1 голос
/ 24 июля 2013

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

int file_exist (char *filename)
{
    char s[200];
    sprintf(s, "test -e %s", filename);
    if (system(s) == 0){
        return 1;
    }else{
        return 0;
    }
}
1 голос
/ 30 сентября 2010

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

0 голосов
/ 30 сентября 2010

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

...