Question

I am iterating through all files in a directory recursively using the following:

try
{
    for ( bf::recursive_directory_iterator end, dir("./");
          dir != end; ++dir )
    {
       const bf::path &p = dir->path();
       if(bf::is_regular_file(p))
       {
           std::cout << "File found: " << p.string() << std::endl;
       }
    }
} catch (const bf::filesystem_error& ex) {
    std::cerr << ex.what() << '\n';
}

But this includes hidden files and files in hidden directories.

How do I filter out these files? If needed I can limit myself to platforms where hidden files and directories begin with the '.' character.

Was it helpful?

Solution

Unfortunately there doesn't seem to be a cross-platform way of handling "hidden". The following works on Unix-like platforms:

First define:

bool isHidden(const bf::path &p)
{
    bf::path::string_type name = p.filename();
    if(name != ".." &&
       name != "."  &&
       name[0] == '.')
    {
       return true;
    }

    return false;
}

Then traversing the files becomes:

try
{
    for ( bf::recursive_directory_iterator end, dir("./");
           dir != end; ++dir)
    {
       const bf::path &p = dir->path();

       //Hidden directory, don't recurse into it
       if(bf::is_directory(p) && isHidden(p))
       {
           dir.no_push();
           continue;
       }

       if(bf::is_regular_file(p) && !isHidden(p))
       {
           std::cout << "File found: " << p.string() << std::endl;
       }
    }
} catch (const bf::filesystem_error& ex) {
    std::cerr << ex.what() << '\n';
}

OTHER TIPS

Let's assume for now that you want to ignore files which start with a '.'. This is the standard indication in Unix for a hidden file. I suggest writing a recursive function to visit each file. In pseudocode, it looks something like this:

visitDirectory dir
    for each file in dir
        if the filename of file does not begin with a '.'
            if file is a directory
                visitDirectory file
            else
                do something with file (perhas as a separate function call?)

This avoids the need to search the whole path of a file to determine whether or not we want to deal with it. Instead, we simply skip any directories which are "hidden."

I can think of several iterative solutions as well, if that's what you prefer. One is to have a stack or queue to keep track of which directory to visit next. Basically this emulates the recursive version with your own data structure. Alternatively, if you are stuck on parsing the full path of the file, simply make sure you get the absolute path. This will guarantee that you don't encounter a directory with a name like './' or '../', which would cause problems with checking for a hidden file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top