Opened 8 years ago

Last modified 5 years ago

#4494 assigned Feature Requests

recursive_directory_iterator throws unexpectedly in the non-throw mode

Reported by: ttan@… Owned by: Beman Dawes
Milestone: Boost 1.44.0 Component: filesystem
Version: Boost Development Trunk Severity: Problem
Keywords: filesystem v3 throw Cc:

Description

In boost::filesystem v3, while it’s possible to choose a no-throw version of recursive_directory_iterator by passing an boost::system::error_code object to its constructor, like this:

boost::system::error_code m_ec; for ( recursive_directory_iterator itr(root, m_ec), end_itr; itr != end_itr; ++itr)

However, because in the implementation of the recursive_directory_iterator::increment(), directory_iterator is always constructed with the throw version, it would cause exception throws during the for-loop while accessing folders like \System Volume Information on Windows:

void increment() {

BOOST_ASSERT(m_imp.get() && "increment of end recursive_directory_iterator"); m_imp->increment(0); if (m_imp->m_stack.empty()) m_imp.reset(); done, so make end iterator

}

Where m_imp is an object of recur_dir_itr_imp:

void recur_dir_itr_imp::increment(system::error_code* ec) ec == 0 means throw on error

{ … }

As it’s not possible to catch this exception within the for-loop and continue the loop, it greatly limits the use of recursive_directory_iterator. With a rough check, V2 does not seem to have this problem. it's preferred that the directory_iterator to behave the same as recursive_directory_iterator in this case.

Change History (3)

comment:1 Changed 8 years ago by zsolt.ero@…

After numerous un-answered posts to the boost-users list, finally I found out that not I am the first one with this problem. I clearly think it's not a feature request, it a bug!

If you use a directory iterator, you can make a recursive function for it, and inside this function you can use try-catch, which will work fine. But with recursive_directory_iterator there is no way to use it for example parse a root folder on a Windows PC I found the same experience:

  1. you need to provide a exception handling _inside_ the for loop, for normal errors, like missing, path not found, etc., which can continue within the loop
  2. and one outside, just for the "not accessible" error, which terminates the loop
  3. Even if you do a while... loop with an if {it++} at the end, there is no function which would check if the it++ will work or not. All the is_something passes fine. It's only when the iterating actually happens, that a exception is thrown, which happens outside the for/while loop, thus not possible to catch it inside.

comment:2 Changed 8 years ago by Beman Dawes

Status: newassigned

comment:3 Changed 5 years ago by anonymous

#define HDIR_DEEP_ITERATOR_BASE boost::filesystem::recursive_directory_iterator

class dir_deep_iterator : public HDIR_DEEP_ITERATOR_BASE

{

public:

.....

dir_deep_iterator & operator ++()

{

try

{

return (dir_deep_iterator &)HDIR_DEEP_ITERATOR_BASE::operator ++();

}

catch(...)

{

有些特殊的目录无法打开,比如"System Volume Information",导致抛出异常

no_push(true);

return (dir_deep_iterator &)HDIR_DEEP_ITERATOR_BASE::operator ++();

}

}

....

}

Note: See TracTickets for help on using tickets.