C ++ - 确定Linux中是否存在目录(不是文件)

时间:2011-02-12 21:43:31

标签: c++ linux directory exists

如何在Linux中使用C ++确定目录(不是文件)是否存在?我尝试使用stat()函数,但在找到文件时返回正数。我只想查找输入的字符串是否是目录,而不是其他内容。

6 个答案:

答案 0 :(得分:29)

根据man(2) stat,您可以在st_mode字段上使用S_ISDIR宏:

bool isdir = S_ISDIR(st.st_mode);

旁注,如果您的软件可以在其他操作系统上运行,我建议使用Boost和/或Qt4来简化跨平台支持。

答案 1 :(得分:15)

我找到了here

的内容
#include <dirent.h>

bool DirectoryExists( const char* pzPath )
{
    if ( pzPath == NULL) return false;

    DIR *pDir;
    bool bExists = false;

    pDir = opendir (pzPath);

    if (pDir != NULL)
    {
        bExists = true;    
        (void) closedir (pDir);
    }

    return bExists;
}

或使用stat

struct stat st;
if(stat("/tmp",&st) == 0)
    if(st.st_mode & S_IFDIR != 0)
        printf(" /tmp is present\n");

答案 2 :(得分:10)

如果您可以查看boost filesystem library。这是以通用和可移植的方式处理此类问题的好方法。

在这种情况下,只需使用:

#include "boost/filesystem.hpp"   
using namespace boost::filesystem; 
...
if ( !exists( "test/mydir" ) ) {bla bla}

答案 3 :(得分:6)

我理解你的问题的方法是:你有一条路径,比如/foo/bar/baz(baz是一个文件),你想知道/foo/bar是否存在。如果是这样,解决方案看起来像这样(未经测试):

char *myDir = dirname(myPath);
struct stat myStat;
if ((stat(myDir, &myStat) == 0) && (((myStat.st_mode) & S_IFMT) == S_IFDIR)) {
    // myDir exists and is a directory.
}

答案 4 :(得分:1)

如果你想知道一个目录是否存在,因为你想对它做一些事情(在里面创建一个文件/目录,扫描它的内容等)你应该继续做任何你想做的事情,然后检查它是否失败,如果是,则向用户报告strerror(errno)。这是在Unix下编程的一般原则:不要试图弄清楚你想要做的事情是否会起作用。尝试它,然后看它是否失败。

如果由于某个目录不存在而失败(例如,如果要创建文件和所有必需的包含目录),那么如果您想要特别表现,那么请在errno == ENOENT之后检查{ {1}}失败。

我看到一位响应者建议使用open。我会喜欢赞同这个建议,但遗憾的是我不能,因为boost::filesystem不是标题,所有Boost的非标题模块都有可怕的记录导致神秘如果在不重新编译应用程序的情况下升级共享库,或者即使您没有设法使用完全编译共享库的相同标志来编译应用程序,也会破坏。维护悲伤是不值得的。

答案 5 :(得分:0)

在C ++ 17 **中,std::filesystem提供了两种变体来确定路径的存在:

  1. is_directory()确定路径是否是目录并且确实存在于实际文件系统中
  2. exists()只是确定实际文件系统中是否存在路径(不检查,是否是目录)
  3. 示例(没有错误处理):

    #include <iostream>
    #include <filesystem> // C++17
    //#include <experimental/filesystem> // C++14
    namespace fs = std::filesystem;
    //namespace fs = std::experimental::filesystem; // C++14
    
    int main()
    {
        // Prepare.
        const auto processWorkingDir = fs::current_path();
        const auto existingDir = processWorkingDir / "existing/directory"; // Should exist in file system.
        const auto notExistingDir = processWorkingDir / "fake/path";
        const auto file = processWorkingDir / "file.ext"; // Should exist in file system.
    
        // Test.
        std::cout
            << "existing dir:\t" << fs::is_directory(existingDir) << "\n"
            << "fake dir:\t" << fs::is_directory(notExistingDir) << "\n"
            << "existing file:\t" << fs::is_directory(file) << "\n\n";
    
        std::cout
            << "existing dir:\t" << fs::exists(existingDir) << "\n"
            << "fake dir:\t" << fs::exists(notExistingDir) << "\n"
            << "existing file:\t" << fs::exists(file);
    }
    

    可能的输出:

    existing dir:   1
    fake dir:       0
    existing file:  0
    
    existing dir:   1
    fake dir:       0
    existing file:  1
    

    **在C ++ 14中std::experimental::filesystem可用

    如果出现错误,两个函数都会抛出filesystem_error。如果您想避免捕获异常,请使用带有std::error_code的重载变量作为第二个参数。

    #include <filesystem>
    #include <iostream>
    namespace fs = std::filesystem;
    
    bool isExistingDir(const fs::path& p) noexcept
    {
        try
        {
            return fs::is_directory(p);
        }
        catch (std::exception& e)
        {
            // Output the error message.
            const auto theError = std::string{ e.what() };
            std::cerr << theError;
    
            return false;
        }
    }
    
    bool isExistingDirEC(const fs::path& p) noexcept
    {
        std::error_code ec;
        const auto isDir = fs::is_directory(p, ec);
        if (ec)
        {
            // Output the error message.
            const auto theError = ec.message();
            std::cerr << theError;
    
            return false;
        }
        else
        {
            return isDir;
        }
    }
    
    int main()
    {
        const auto notExistingPath = fs::path{ "\xa0\xa1" };
        isExistingDir(notExistingPath);
        isExistingDirEC(notExistingPath);
    }