7

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

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

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

但是我该怎么做呢?

4

2 回答 2

9

哈,想通了,有办法:

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

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

于 2013-04-12T12:20:06.440 回答
1

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

这是一个更正的版本:

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;
}
于 2018-03-29T12:21:44.217 回答