繁体   English   中英

检查 Unix 中是否存在目录(系统调用)

[英]Checking if a directory exists in Unix (system call)

我无法在网上找到解决我的问题的方法。

我想在 Unix 中调用一个函数,传入一个目录的路径,并知道它是否存在。 如果目录不存在, opendir()将返回错误,但我的目标不是实际打开,检查错误,如果没有错误则关闭它,而只是检查文件是否为目录。

请问有什么方便的方法吗?

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...
}

如果函数指示它成功,则使用<sys/stat.h>中的 S_ISDIR() 宏来确定文件是否实际上是目录。

您还可以使用其他S_IS*宏检查其他文件类型:

  • S_ISDIR — 目录
  • S_ISREG — 常规文件
  • S_ISCHR — 字符设备
  • S_ISBLK — 块设备
  • S_ISFIFO — 先进先出
  • S_ISLNK — 符号链接
  • S_ISSOCK — 套接字

(一些系统还提供了一些其他文件类型;例如, S_ISDOOR在 Solaris 上可用。)

您可以通过将目录名称作为第一个参数传递给stat系统调用来使用它。 如果目录存在则返回0否则返回-1并且 errno 将被设置为ENOENT

编辑:

如果返回值为0 ,则需要额外检查以确保参数实际上是一个目录,而不是 file/symlink/char 特殊文件/blk 特殊文件/FIFO 文件。 为此,您可以使用stat structurest_mode字段。

如果你是在谈论shell,那么这里有一个很好的答案 总结一下答案:

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");
}

你可以使用test -d

经过测试和正常工作:

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

如果您并不真正关心此文件系统对象的类型,那么 access(name, F_OK) 会检查是否存在具有此名称的内容。 如果您需要确定这是目录,请使用 stat() 并使用 S_ISDIR() 宏检查类型。

另一种简单的方法是:

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

然后,您可以将struct dirent*对象的 d_type 传递给检查函数。

如果检查返回 1,则该路径指向常规文件。

如果检查返回 0,则该路径指向一个目录。

否则,它既不是文件也不是目录(可以是块设备/符号链接等)

我认为函数stat可以做你想要的(我没有测试它的目录)。 在C ++中,您还可以使用boost :: filesystem库。

C++17

使用std::filesystem::is_directory

#include <filesystem>

void myFunc(const std::filesystem::path& directoryPath_c)
{
    if (std::filesystem::is_directory(directoryPath_c)) {
    //if (std::filesystem::exists(directoryPath_c)) { // Alternative*
        // do something.
    }
}

或者在它的noexept版本中:

#include <filesystem>

void myFunc(const std::filesystem::path& directoryPath_c)
{
    std::error_code ec{};
    if (std::filesystem::is_directory(directoryPath_c, ec)) {
    //if (std::filesystem::exists(directoryPath_c, ec)) { // An alternative*
        // do something.
    }
}
  • 替代方法的缺点是,如果directoryPath_c作为常规文件存在,则std::filesystem::exists(directoryPath_c)将返回true ,尽管该文件夹不存在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM