c++fileubuntufilesystemsfilepath

C++17 create directories automatically given a file path


#include <iostream>
#include <fstream>
using namespace std;
    
int main()
{
    ofstream fo("output/folder1/data/today/log.txt");
    fo << "Hello world\n";
    fo.close();
    
    return 0;
}

I need to output some log data to some files with variable names. However, ofstream does not create directories along the way, if the path to the file doesn't exist, ofstream writes to nowhere!

What can I do to automatically create folders along a file path? The system is Ubuntu only.


Solution

  • You can use this function (CreateDirectoryRecursive) to achieve that, as shown below.

    It uses std::filesystem::create_directories and std::filesystem::exists.

    #include <string>
    #include <filesystem>
    
    // Returns:
    //   true upon success.
    //   false upon failure, and set the std::error_code & err accordingly.
    bool CreateDirectoryRecursive(std::string const & dirName, std::error_code & err)
    {
        err.clear();
        if (!std::filesystem::create_directories(dirName, err))
        {
            if (std::filesystem::exists(dirName))
            {
                // The folder already exists:
                err.clear();
                return true;    
            }
            return false;
        }
        return true;
    }
    

    Usage example:

    #include <iostream>
    
    int main() 
    {
        std::error_code err;
        if (!CreateDirectoryRecursive("/tmp/a/b/c", err))
        {
            // Report the error:
            std::cout << "CreateDirectoryRecursive FAILED, err: " << err.message() << std::endl;
        }
    }
    

    Note:

    <filesystem> is available since c++-17.
    Before that it was available in many compilers via the <experimental/filesystem> header.