Traversing a directory with boost::filesystem without throwing exceptions

久未见 提交于 2019-12-22 06:44:45

问题


I have a path to the directory, and I want to traverse through all of its sub-directories, collecting files' pathes by the way.

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

Unfortunately, in the middle of the traversing, I stumble upon a directory which I have no rights to look at, and the code above throws. But obviously, in this scenario it's not an exception, I should just go on, skipping this locked directory.

But how do I do this?


回答1:


Ha, figured it out, there is a way:

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

There is a non-throwing overload which accepts an output parameter of type boost::system::error_code, so I can just check after each increment if there were any error.




回答2:


Joker_vD's answer crashes when an error occurs for the last directory entry. For example, when the target directory contains a single subdirectory without permissions. The cause is the 'it.pop()' which apparently isn't needed. Also, the 'continue' shouldn't be done, as it would skip the next entry. After an error the iterator already points to the next valid entry, or is equal to the end iterator.

This is a corrected version:

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


来源:https://stackoverflow.com/questions/15970013/traversing-a-directory-with-boostfilesystem-without-throwing-exceptions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!