C++17在给定文件路径的情况下自动创建目录


#include <iostream>
#include <fstream>
using namespace std;

int main()
{
ofstream fo("output/folder1/data/today/log.txt");
fo << "Hello worldn";
fo.close();

return 0;
}

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

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

您可以使用此函数(CreateDirectoryRecursive(来实现这一点,如下所示。

它使用std::filesystem::create_directoriesstd::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;
}

用法示例:

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

注意:

<filesystem>从c++-17开始就可用。
在此之前,许多编译器都可以通过<experimental/filesystem>标头使用它。

根据cppreference:

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

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

你能做的是:

  1. 获取要将文件保存到的目录路径(在您的示例中:output/folder1/data/today/(
  2. 获取您的文件名(log.txt(
  3. 创建(所有(文件夹
  4. 使用std::fstream写入您的文件
#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();
}

最新更新