2013-04-19 9 views
5

Sto utilizzando l'iteratore boost "recursive_directory_iterator" per eseguire la scansione in modo ricorsivo attraverso una directory. Tuttavia, quando l'iteratore viene eseguito in una directory per cui la mia applicazione non ha accesso, viene lanciata un'eccezione di tipo "boost :: filesystem3 :: filesystem_error", che interrompe l'iteratore e il programma si interrompe. È comunque possibile istruire l'iteratore per ignorare tali directory.recursive_directory_iterator genera l'eccezione

Ho provato il codice suggerito allo Traversing a directory with boost::filesystem without throwing exceptions Tuttavia, non ha funzionato né funzionato per me. Sto usando la versione 1.49 di spinta.

Il mio codice dopo aver seguito il suggerimento (il meglio che potevo venire con), si presenta come segue:

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

Grazie, Ahmed.

+0

Ho aggiornato la parte di incremento del ciclo for, e ora ho un errore diverso: ***** Errore programma interno - assertion (m_level> 0) non riuscito in void boost :: filesystem3 :: dettaglio :: recur_dir_itr_imp :: pop(): /usr/include/boost/filesystem/v3/operations.hpp(818): pop() su recursive_directory_iterato r con livello <1 abortito –

+0

Apparentemente questo è un noto (ancora da risolvere) bug: https://svn.boost.org/trac/boost/ticket/4494 –

+0

Ho lo stesso problema. Ancora non è stato risolto nell'aprile 2015? –

risposta

0

È possibile utilizzare i blocchi try-catch e se si cattura boost :: :: filesystem3 filesystem_error allora si può saltare l'iterazione corrente:

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

Sono novizio di C++, ma come utilizzare un blocco try-catch per un'istruzione in un ciclo for. Immagino che un'opzione sia quella di trasformare il ciclo for in un ciclo while. Lo proverò. –

5

Questo è un bug noto in boost :: filesystem (V3) : https://svn.boost.org/trac/boost/ticket/4494. A seconda delle esigenze, è possibile utilizzare V2 della libreria (potrebbe anche venire con il compilatore sotto forma di std::tr2::filesystem). Un'altra opzione è quella di implementare la parte ricorsiva da soli.

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

Il codice sopra riportato è solo per dare un'idea generale, manca il controllo degli errori tra le altre cose.