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