8

ブーストイテレータ「recursive_directory_iterator」を使用して、ディレクトリを再帰的にスキャンしています。ただし、アプリケーションがアクセスできないディレクトリに反復子が実行されると、タイプ「boost::filesystem3::filesystem_error」の例外がスローされ、反復子が停止し、プログラムが中止されます。とにかく、イテレータにそのようなディレクトリをスキップするように指示できますか?

Traversing a directory with boost::filesystem without throwing exceptions で提案されているコードを試しましたが 、うまくいきませんでした。ブースト バージョン 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;
    }
}

ありがとう、アーメド。

4

3 に答える 3

8

これは、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;
  }
}

上記のコードは一般的な考え方を示すためのものであり、とりわけエラーチェックが欠落しています。

于 2014-04-17T14:30:21.247 に答える
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++;
   }
}
于 2013-04-19T09:14:26.430 に答える
0

アンドレアス答えに基づいて構築します。std::experimentalv2 も も持っていない場合は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(...)
        {}
于 2019-12-24T14:00:21.480 に答える