【问题标题】:Portably testing for folders in C++?可移植地测试 C++ 中的文件夹?
【发布时间】:2017-02-04 13:52:57
【问题描述】:

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

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 似乎不起作用,我如何可移植地检查目录?

【问题讨论】:

  • 试试 Boost.Filesystem。
  • 这里有点迂腐的琐事,但并非所有文件系统都有文件夹的概念。特别是大型机没有。希望您永远不需要知道这一点,但以防万一……好吧,就是这样。

标签: c++ stat dirent.h


【解决方案1】:

对于初学者,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");
 }

【讨论】:

  • 我做了更改,但没有解决;无论如何,我在添加异常之前注意到了这个错误,因为它试图将文件作为文件夹打开。
【解决方案2】:

这似乎是最可靠的:

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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 2010-10-02
    相关资源
    最近更新 更多