0

I'm trying to retrieve all files from the C:/ directory using Boost library.

I can retrieve all files when the input is a file path with a directory (e.g : C:\Windows), but I get an error when the specified path is only C:\. I also tried with C: but Boost search file from my project directory and not from the root.

I have also added an exclusion to C:\Windows and this part works great.

So how to launch recursive_directory_iterator from C:\ ?

Here is my code :

//string rootPath = boost::filesystem::current_path().root_directory().string();
string rootPath = "C:";
string exclusionPath = rootPath+"\\"+"Windows";

void myClass::getFile()
{ 

   for (boost::filesystem::recursive_directory_iterator end, dir(rootPath); dir != end; ++dir)
   {   

    string filePath = dir->path().string();
    
    if (boost::filesystem::is_regular_file(*dir) && filePath.find(exclusionPath) == string::npos)
    {
        cout << filePath << endl;
    }
  }
}
Sad1que
  • 37
  • 6
  • 2
    Don't use boost for that, you have a [standard C++ way](https://en.cppreference.com/w/cpp/filesystem/recursive_directory_iterator) now. SO question [here](https://stackoverflow.com/questions/67273/how-do-you-iterate-through-every-file-directory-recursively-in-standard-c) – Michael Chourdakis Jul 20 '21 at 19:01
  • 1
    You state `"...but I get an error when the specified path is only C:\"`: please show the error as text verbatim. – G.M. Jul 20 '21 at 19:03
  • @G.M. Here the error I got : Unhandled exception at 0x00007FFA48BA4ED9 in program.exe: Microsoft C++ exception: boost::filesystem::filesystem_error at memory location 0x000000B9796FF020. – Sad1que Jul 20 '21 at 19:08
  • @MichaelChourdakis, Ok I will test the standard library but I saw that boost was faster, I don't know – Sad1que Jul 20 '21 at 19:10
  • @Sad1que [`filesystem_error`](https://www.boost.org/doc/libs/1_33_1/libs/filesystem/doc/exception.htm) has several non-static members to describe the underlying OS error (`native_error()`, `error()`, `who()`, `what()`, and `path1()`). What do they actually say? Either the path you are specifying is wrong to begin with, or you probably don't have security rights to access it. – Remy Lebeau Jul 20 '21 at 20:09
  • If you are using NTFS, consider parsing the MFT file, as it will be much faster than using `recursive_directory_iterator`. – janekb04 Jul 20 '21 at 20:35

1 Answers1

0

If you are using the c++17 standard library, you can take advantage of the standard filesystem library. It works just like the boost filesystem and the two libraries have a very similar API. You have to include the filesystem header via

#include <filesystem>

You can recursively iterate through each file in a directory by calling:

for (std::filesystem::directory_entry entry : std::filesystem::recursive_directory_iterator(rootPath))

That will give you a directory entry, which, just like the boost directory entry, contains a path. I was able to replicate your example code with the standard library and got a working example like so:

#include <filesystem>
#include <string>
#include <iostream>

std::filesystem::path rootPath = "C:";
std::filesystem::path exclusionPath = rootPath / "Windows";

int main()
{
    for (std::filesystem::directory_entry entry : std::filesystem::recursive_directory_iterator(rootPath))
    {
        std::string filePath = entry.path().string();

        if (std::filesystem::is_regular_file(entry.path()) && filePath.find(exclusionPath.string()) == std::string::npos)
        {
            std::cout << filePath << std::endl;
        }
    }
}

As you can see, I converted the strings you use for paths above to paths. This is not necessary but it is better to construct a path up-front, because else every function you call will construct a new path with the string you put into it. Paths weirdly use the / operator to append two paths together, so on Windows

std::filesystem::path exclusionPath = rootPath / "Windows";

will give you C:\Windows.

NettySocket
  • 111
  • 2
  • 11