Recursive_directory_iterator抛出异常

recursive_directory_iterator throws exception

本文关键字:抛出异常 iterator directory Recursive      更新时间:2023-10-16

我使用boost迭代器"recursive_directory_iterator"递归扫描目录。但是,当迭代器运行到一个我的应用程序无法访问的目录时,抛出类型为"boost::filesystem3::filesystem_error"的异常,该异常会停止迭代器并终止程序。有没有办法让迭代器跳过这样的目录?

我尝试了在使用boost::filesystem遍历目录而不抛出异常时建议的代码,但是,它对我不起作用。我正在使用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;
    }
}

谢谢你,艾哈迈德。

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

上面的代码只是给了一个大致的概念,错误检查和其他功能是缺失的。

你可以使用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++;
   }
}

以andreas的回答为基础。如果你既没有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(...)
        {}