如何禁用Boost recursive_directory_iterator的异常抛出?
Boost Filesystem递归遍历目录的权限异常处理问题
我使用Ubuntu 20.04、C11和Boost Filesystem 1.71,尝试在C中遍历包含当前用户无权限访问元素的目录,但遇到此类元素时总会触发异常。我原本以为指定error_code后就不会抛出异常了?
初始代码
#include <iostream> #include <cstdlib> #include <string> #include <exception> #define BOOST_FILESYSTEM_NO_DEPRECATED #include <boost/filesystem.hpp> namespace fs = boost::filesystem; void sometest(const fs::path &f) { boost::system::error_code ec; auto begin = fs::recursive_directory_iterator(f, ec); const auto end = fs::recursive_directory_iterator(); for (auto it = begin; it != end; ++it) { std::cout << it->path().string() << std::endl; } } int main() { int result = EXIT_FAILURE; try { sometest("/tmp"); result = EXIT_SUCCESS; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; } return result; }
更新1:修正迭代器增量方式,但出现无限打印问题
我意识到是赋值操作导致error对象失效,进而引发了异常抛出。以下是更新后的代码版本:
#include <iostream> #include <cstdlib> #include <string> #include <exception> #define BOOST_FILESYSTEM_NO_DEPRECATED #include <boost/filesystem.hpp> namespace fs = boost::filesystem; void sometest1(const fs::path &f) { boost::system::error_code ec; auto it = fs::recursive_directory_iterator(f, ec); auto end = fs::recursive_directory_iterator(); for (; it != end; it.increment(ec)) { std::cout << it->path().string() << std::endl; } } int main() { int result = EXIT_FAILURE; try { sometest1("/tmp"); result = EXIT_SUCCESS; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; } return result; }
修改后,程序会列出目录元素直到遇到权限问题的元素,随后会无限打印该元素。
更新2:添加错误检查,发现迭代器失效
将函数修改为如下形式:
void sometest1(const fs::path &f) { boost::system::error_code ec; auto it = fs::recursive_directory_iterator(f, ec); auto end = fs::recursive_directory_iterator(); while ( it != end ) { std::cout << it->path().string() << std::endl; it.increment(ec); if (ec.failed()) { std::cout << ec.message() << std::endl; if (it == end) { std::cout << "Ending" << std::endl; } } } }
得到如下输出:
/tmp/instantclient-basic-linuxx64.zip.1 /tmp/origdir /tmp/mc-darko /tmp/tmp.N3DqnDv5gf /tmp/tmp.N3DqnDv5gf/ijent /tmp/7E5SS5 /tmp/mc-root Permission denied Ending
可见发生错误后迭代器会失效,且无法避免。
结论
若需使用Boost Filesystem库V3(Boost 1.44及以上版本提供)且无法使用V4(Boost 1.77及以上版本提供),则必须避免使用recursive_directory_iterator。
内容的提问来源于stack exchange,提问作者Darko Miletic
相关产品推荐
相关产品推荐

