Boost C++ Libraries: Ticket #4494: recursive_directory_iterator throws unexpectedly in the non-throw mode https://svn.boost.org/trac10/ticket/4494 <p> 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: </p> <blockquote> <p> boost::system::error_code m_ec; for ( recursive_directory_iterator itr(root, m_ec), end_itr; itr != end_itr; ++itr) </p> </blockquote> <p> 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: </p> <blockquote> <p> void increment() { </p> <blockquote> <p> BOOST_ASSERT(m_imp.get() &amp;&amp; "increment of end recursive_directory_iterator"); m_imp-&gt;increment(0); if (m_imp-&gt;m_stack.empty()) m_imp.reset(); <em> done, so make end iterator </em></p> </blockquote> </blockquote> <p> } </p> <p> Where m_imp is an object of recur_dir_itr_imp: </p> <blockquote> <p> void recur_dir_itr_imp::increment(system::error_code* ec) <em> ec == 0 means throw on error </em></p> </blockquote> <p> { … } </p> <p> 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. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/4494 Trac 1.4.3 zsolt.ero@… Sat, 27 Nov 2010 20:35:22 GMT <link>https://svn.boost.org/trac10/ticket/4494#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4494#comment:1</guid> <description> <p> 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! </p> <p> 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 <strong>with recursive_directory_iterator there is no way to use it</strong> for example parse a root folder on a Windows PC I found the same experience: </p> <ol><li>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 </li><li>and one outside, just for the "not accessible" error, which terminates the loop </li><li>Even if you do a while... loop with an if {it++} at the end, <strong>there is no function which would check</strong> 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. </li></ol> </description> <category>Ticket</category> </item> <item> <dc:creator>Beman Dawes</dc:creator> <pubDate>Sat, 04 Dec 2010 13:09:27 GMT</pubDate> <title>status changed https://svn.boost.org/trac10/ticket/4494#comment:2 https://svn.boost.org/trac10/ticket/4494#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket anonymous Sat, 31 Aug 2013 15:54:02 GMT <link>https://svn.boost.org/trac10/ticket/4494#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4494#comment:3</guid> <description> <p> #define HDIR_DEEP_ITERATOR_BASE boost::filesystem::recursive_directory_iterator </p> <p> class dir_deep_iterator : public HDIR_DEEP_ITERATOR_BASE </p> <p> { </p> <p> public: </p> <blockquote> <p> ..... </p> </blockquote> <blockquote> <p> dir_deep_iterator &amp; operator ++() </p> </blockquote> <blockquote> <p> { </p> </blockquote> <blockquote> <blockquote> <p> try </p> </blockquote> </blockquote> <blockquote> <blockquote> <p> { </p> </blockquote> </blockquote> <blockquote> <blockquote> <blockquote> <p> return (dir_deep_iterator &amp;)HDIR_DEEP_ITERATOR_BASE::operator ++(); </p> </blockquote> </blockquote> </blockquote> <blockquote> <blockquote> <p> } </p> </blockquote> </blockquote> <blockquote> <blockquote> <p> catch(...) </p> </blockquote> </blockquote> <blockquote> <blockquote> <p> { </p> </blockquote> </blockquote> <blockquote> <blockquote> <blockquote> <p> <em>有些特殊的目录无法打开,比如"System Volume Information",导致抛出异常 </em></p> </blockquote> </blockquote> </blockquote> <blockquote> <blockquote> <blockquote> <p> no_push(true); </p> </blockquote> </blockquote> </blockquote> <blockquote> <blockquote> <blockquote> <p> return (dir_deep_iterator &amp;)HDIR_DEEP_ITERATOR_BASE::operator ++(); </p> </blockquote> </blockquote> </blockquote> <blockquote> <blockquote> <p> } </p> </blockquote> </blockquote> <blockquote> <p> } </p> </blockquote> <blockquote> <p> .... </p> </blockquote> <p> } </p> </description> <category>Ticket</category> </item> </channel> </rss>