在C ++中可以轻松测试文件夹?

时间:2017-02-04 13:52:57

标签: c++ stat dirent.h

我的基本问题是这段代码几乎总是抛出异常:

bool DirectoryRange::isDirectory() const
{
    struct stat s;
    stat(ep->d_name, &s);

#if defined(__linux__)
    if((S_ISDIR(s.st_mode) != 0) != (ep->d_type == DT_DIR))
    {
        throw std::logic_error("Directory is not directory");
    }
#endif

    return S_ISDIR(s.st_mode);
}

bool DirectoryRange::isFile() const
{
    struct stat s;
    stat(ep->d_name, &s);

#if defined(__linux__)
    if((S_ISREG(s.st_mode) != 0) != (ep->d_type == DT_REG))
    {
        throw std::logic_error("File is not file");
    }
#endif

    return S_ISREG(s.st_mode);
}

检查dirent值是不可移植的,但是得到了正确的答案;虽然stat是错误的,但是便于携带。

那么,如果stat似乎无法正常工作,我如何便携地检查目录?

2 个答案:

答案 0 :(得分:0)

对于初学者,S_ISDIRnot a macro that returns a boolean value

  

如果测试为真,则宏评估为非零值,如果为,则为0   测试是错误的。

     

...

     

S_ISDIR(m) - 测试目录。

(强调我的)。对bool的显式转换是错误的,并且没有任何用处。使用此宏(和其他S_..宏)的正确方法是:

 if(S_ISDIR(s.st_mode) == 0)
 {
      throw std::logic_error("Directory is not a Directory");
 }

答案 1 :(得分:0)

这似乎最可靠:

bool DirectoryRange::isDirectory() const
{
#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
    return ep->d_type == DT_DIR;
#else 
    auto path = syspath();
    DIR * dp = opendir(path.c_str());
    if(dp) closedir(dp);
    return dp;
#endif
}

bool DirectoryRange::isFile() const
{
#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
    return ep->d_type == DT_REG;
#else 
    auto path = syspath();
    FILE * fp = fopen(path.c_str(), "r");
    if(fp) fclose(fp);
    return fp;
#endif
}