C++17 根据文件路径自动创建目录

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

我需要输出一些日志数据到一些变量名的文件中。但是,ofstream 不会在途中创建目录,如果文件路径不存在,ofstream 将无处写入!

如何沿着文件路径自动创建文件夹?该系统仅 Ubuntu。

你可以使用这个功能:

bool CreateDirectoryRecuresive(const std::string & dirName)
{
    std::error_code err;
    if (!std::experimental::filesystem::create_directories(dirName, err))
    {
        if (std::experimental::filesystem::exists(dirName))
        {
            return true;    // the folder probably already existed
        }

        printf("CreateDirectoryRecuresive: FAILED to create [%s], err:%s\n", dirName.c_str(), err.message().c_str());
        return false;
    }
    return true;
}

(如果你有足够新的标准库,你可以去掉experimental部分)。

代码中使用的方法的文档:

  1. std::filesystem::create_directories.
  2. std::filesystem::exists.

根据cppreference

bool create_directories(const std::filesystem::path& p);

p 中尚不存在的每个元素创建一个目录。如果 p 已经存在,则该函数不执行任何操作。 returns true 如果为目录 p 创建了一个目录,则 false 否则解析为 false

您可以做的是:

  1. 获取要将文件保存到的目录路径(在您的示例中:output/folder1/data/today/)。
  2. 获取您的文件名 (log.txt)。
  3. 创建(全部)您的文件夹。
  4. 使用 std::fstream.
  5. 写入您的文件
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#include <filesystem>

namespace fs = std::filesystem;

// Split a string separated by sep into a vector
std::vector<std::string> split(const std::string& str, const char sep)
{
    std::string token; 
    std::stringstream ss(str);
    std::vector<std::string> tokens;
    
    while (std::getline(ss, token, sep)) {
        tokens.push_back(token);
    }
    
    return tokens;
}

int main()
{
    std::string path = "output/folder1/data/today/log.txt";
    
    std::vector<std::string> dirs = split(path, '/');
    
    if (dirs.empty())
        return 1;
    
    std::string tmp = "./"; // Current dir
    for (auto it = dirs.begin(); it != std::prev(dirs.end()); ++it)
        tmp += *it + '/';
    
    fs::create_directories(tmp);
    
    std::ofstream os(tmp + dirs.back());
    os << "Some text...\n";
    os.close();
}