使用boost :: filesystem遍历目录而不抛出异常

时间:2013-04-12 11:19:34

标签: c++ boost boost-filesystem

我有一个目录路径,我想遍历所有子目录,顺便收集文件的路径。

namespace fs = boost::filesystem;

std::vector<fs::path> traverse_if_directory(fs::path& f) {
    std::vector<fs::path> result;
    if (fs::is_directory(f)) {      
        for (fs::recursive_directory_iterator it(f), eit; it != eit; ++it) {
            if (!fs::is_directory(it->path())) {
                result.push_back(it->path());
            }       
        }
    }
    else {
        result.push_back(f);
    }

    return result;
}

不幸的是,在遍历的过程中,我偶然发现了一个我无权查看的目录,并且上面的代码抛出了。但显然,在这种情况下,这不是一个例外,我应该继续,跳过这个锁定的目录。

但是我该怎么做?

2 个答案:

答案 0 :(得分:8)

哈,想通了,有办法:

std::vector<fs::path> traverse_if_directory(fs::path& f) {
    std::vector<fs::path> result;
    boost::system::error_code ec;

    if (fs::is_directory(f)) {      
        for (
             fs::recursive_directory_iterator it(f, ec), eit;
             it != eit;
             it.increment(ec)
            ) {
            if (ec) {
                it.pop();
                continue;
            }
            if (!fs::is_directory(it->path())) {
                result.push_back(it->path());
            }
        }
    }
    else {
        result.push_back(f);
    }

    return result;
}

有一个非抛出重载接受类型为boost::system::error_code的输出参数,因此我可以在每次增量后检查是否有任何错误。

答案 1 :(得分:1)

当最后一个目录条目发生错误时,Joker_vD的答案崩溃了。例如,当目标目录包含没有权限的单个子目录时。原因是&#39; it.pop()&#39;显然不需要。此外,&#39;继续&#39;不应该这样做,因为它会跳过下一个条目。发生错误后,迭代器已经指向下一个有效条目,或者等于结束迭代器。

这是更正版本:

std::vector<fs::path> traverse_if_directory(const fs::path& f) {
    std::vector<fs::path> result;
    boost::system::error_code ec;

    if (fs::is_directory(f)) {
        for (fs::recursive_directory_iterator it{f, ec}, end; it != end; it.increment(ec)) {
            if (!fs::is_directory(it->path())) {
                result.push_back(it->path());
            }
        }
    }
    else {
        result.push_back(f);
    }

    return result;
}