我正在使用boost迭代器“recursive_directory_iterator”以递归方式扫描目录。但是,当迭代器运行到我的应用程序无法访问的目录时,抛出类型“boost :: filesystem3 :: filesystem_error”的异常,这会停止迭代器并且程序将中止。无论如何,我可以指示迭代器跳过这些目录。
我尝试了Traversing a directory with boost::filesystem without throwing exceptions建议的代码但是,它确实对我不起作用。我正在使用boost版本1.49。
我的代码遵循了建议(我能想到的最好的),看起来如下:
void scand()
{
boost::system::error_code ec, no_err;
// Read dir contents recurs
for (recursive_directory_iterator end, _path("/tmp", ec);
_path != end; _path.increment(ec)) {
if (ec != no_err) {
_path.pop();
continue;
}
cout << _path->path() << endl;
}
}
谢谢你, 艾哈迈德。
答案 0 :(得分:6)
这是boost :: filesystem(V3)中的已知错误:https://svn.boost.org/trac/boost/ticket/4494。根据您的需要,您可以使用库的V2(它甚至可能以std::tr2::filesystem
的形式与您的编译器一起使用)。另一个选择是自己实现递归部分。
boost::system::error_code ec;
std::deque<boost::filesystem::path> directories {initialDir};
while(!directories.empty())
{
boost::filesystem::directory_iterator dit(directories.front(), ec);
directories.pop_front();
while(dit != boost::filesystem::directory_iterator())
{
if(boost::filesystem::is_directory(dit->path(), ec))
{
directories.push_back(dit->path());
}
HandleFile(dit->path()); // <-- do something with the file
++dit;
}
}
上面的代码只是为了给出一个大致的想法,错误检查以及其他内容都缺失了。
答案 1 :(得分:0)
你可以使用try-catch块,如果你捕获boost :: filesystem3 :: filesystem_error,那么你可以跳过当前的迭代:
void scand()
{
boost::system::error_code ec, no_err;
// Read dir contents recurs
recursive_directory_iterator end;
_path("/tmp", ec);
while (_path != end) {
try
{
if (ec != no_err) {
_path.pop();
continue;
}
cout << _path->path() << endl;
}
catch(boost::filesystem3::filesystem_error e)
{
}
_path++;
}
}
答案 2 :(得分:0)
以andreas'answer为基础。如果您既没有std::experimental
v2也没有boost
,请尝试此操作。它将跳过有问题的文件夹。
namespace fs = std::experimental::filesystem;
for(std::deque<fs::path> directories{{str_to<std::string>(path)}} ; ! directories.empty() ; directories.pop_front())
try {
for(fs::directory_iterator dit(directories.front()) ; dit != fs::directory_iterator() ; ++dit)
if (fs::is_directory(dit->path()))
directories.push_back(dit->path());
else if (fs::is_regular_file(dit->path()))
Handle(dit->path().string());
}
catch(...)
{}