My solution is essentially the same as Julien-L, but encapsulated in an include file which is better to use. Implemented using boost :: filesystem v3. I assume that something like this is not included in boost :: filesystem directly, because it will lead to a dependency on boost :: regex.
#include "FilteredDirectoryIterator.h" std::vector< std::string > all_matching_files; std::for_each( FilteredDirectoryIterator("/my/directory","somefiles.*\.txt"), FilteredDirectoryIterator(), [&all_matching_files](const FilteredDirectoryIterator::value_type &dirEntry){ all_matching_files.push_back(dirEntry.path()); } );
alternatively use FilteredRecursiveDirectoryIterator to search for recursive subdirectories:
#include "FilteredDirectoryIterator.h" std::vector< std::string > all_matching_files; std::for_each( FilteredRecursiveDirectoryIterator("/my/directory","somefiles.*\.txt"), FilteredRecursiveDirectoryIterator(), [&all_matching_files](const FilteredRecursiveDirectoryIterator::value_type &dirEntry){ all_matching_files.push_back(dirEntry.path()); } );
FilteredDirectoryIterator.h
#ifndef TOOLS_BOOST_FILESYSTEM_FILTEREDDIRECTORYITERATOR_H_ #define TOOLS_BOOST_FILESYSTEM_FILTEREDDIRECTORYITERATOR_H_ #include "boost/filesystem.hpp" #include "boost/regex.hpp" #include <functional> template <class NonFilteredIterator = boost::filesystem::directory_iterator> class FilteredDirectoryIteratorTmpl : public std::iterator< std::input_iterator_tag, typename NonFilteredIterator::value_type > { private: typedef std::string string; typedef boost::filesystem::path path; typedef std::function< bool(const typename NonFilteredIterator::value_type &dirEntry) > FilterFunction; NonFilteredIterator it; NonFilteredIterator end; const FilterFunction filter; public: FilteredDirectoryIteratorTmpl(); FilteredDirectoryIteratorTmpl( const path &iteratedDir, const string ®exMask ); FilteredDirectoryIteratorTmpl( const path &iteratedDir, const boost::regex &mask ); FilteredDirectoryIteratorTmpl( const path &iteratedDir, const FilterFunction &filter ); //preincrement FilteredDirectoryIteratorTmpl<NonFilteredIterator>& operator++() { for(++it;it!=end && !filter(*it);++it); return *this; }; //postincrement FilteredDirectoryIteratorTmpl<NonFilteredIterator> operator++(int) { for(++it;it!=end && !filter(*it);++it); return FilteredDirectoryIteratorTmpl<NonFilteredIterator>(it,filter); }; const boost::filesystem::directory_entry &operator*() {return *it;}; bool operator!=(const FilteredDirectoryIteratorTmpl<NonFilteredIterator>& other) { return it!=other.it; }; bool operator==(const FilteredDirectoryIteratorTmpl<NonFilteredIterator>& other) { return it==other.it; }; }; typedef FilteredDirectoryIteratorTmpl<boost::filesystem::directory_iterator> FilteredDirectoryIterator; typedef FilteredDirectoryIteratorTmpl<boost::filesystem::recursive_directory_iterator> FilteredRecursiveDirectoryIterator; template <class NonFilteredIterator> FilteredDirectoryIteratorTmpl<NonFilteredIterator>::FilteredDirectoryIteratorTmpl() : it(), filter( [](const boost::filesystem::directory_entry& /*dirEntry*/){return true;} ) { } template <class NonFilteredIterator> FilteredDirectoryIteratorTmpl<NonFilteredIterator>::FilteredDirectoryIteratorTmpl( const path &iteratedDir,const string ®exMask ) : FilteredDirectoryIteratorTmpl(iteratedDir, boost::regex(regexMask)) { } template <class NonFilteredIterator> FilteredDirectoryIteratorTmpl<NonFilteredIterator>::FilteredDirectoryIteratorTmpl( const path &iteratedDir,const boost::regex ®exMask ) : it(NonFilteredIterator(iteratedDir)), filter( [regexMask](const boost::filesystem::directory_entry& dirEntry){ using std::endl; // return false to skip dirEntry if no match const string filename = dirEntry.path().filename().native(); return boost::regex_match(filename, regexMask); } ) { if (it!=end && !filter(*it)) ++(*this); } template <class NonFilteredIterator> FilteredDirectoryIteratorTmpl<NonFilteredIterator>::FilteredDirectoryIteratorTmpl( const path &iteratedDir, const FilterFunction &filter ) : it(NonFilteredIterator(iteratedDir)), filter(filter) { if (it!=end && !filter(*it)) ++(*this); } #endif
David L. Dec 16 '14 at 8:11 2014-12-16 08:11
source share