I was trying to search for some code examples on how to do a recursive directory search under Linux using C++ the other day. But to my surprise, I could not find any place that offers a complete example. So I decided to post my code here after I created my own and hopefully you will find it helpful.
For those who are impatient, the function to perform recursive directory search is here:
#include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <errno.h> #include <vector> #include <string> #include <iostream> #include <boost/regex.hpp> void GetFileListing(vector<string> &files, string dir, string filter, bool ignoreCase) { DIR *d; if ((d = opendir(dir.c_str())) == NULL) return; if (dir.at(dir.length() - 1) != '/') dir += "/"; struct dirent *dent; struct stat st; boost::regex exp; if (ignoreCase) exp.set_expression(filter, boost::regex_constants::icase); else exp.set_expression(filter); while ((dent = readdir(d)) != NULL) { string path = dir; if (string(dent->d_name) != "." && string(dent->d_name) != "..") { path += string(dent->d_name); const char *p = path.c_str(); lstat(p, &st); if (S_ISDIR(st.st_mode)) { GetFiles(files, (path + string("/")).c_str(), filter, ignoreCase); } else { if (filter == ".*") { files.push_back(path); } else { if (boost::regex_match(string(dent->d_name), exp)) files.push_back(path); } } } } closedir(d); }
I used boost library to perform regular expression matches for file names. If you just want to obtain a listing of all the files, you can do without using the boost library.
The following code snippet demonstrates how to use the function. The results are stored in a vector container passed in. Note that the “filter” parameter needs standard regular expressions (so if you are looking for any files, the expression should be .* instead of just *) to work properly.
The code should be pretty self-explanatory. If ignoreCase is set to true, then the match will be case-insensitive.
vector<string> files; FileUtils::GetFiles(files,"/tmp", ".*", true); for (int i = 0 ; i < files.size(); i++) { cout << files[i] << endl; }