13

我正在用 C++ 编写一个创建临时目录的函数。这样的功能应该尽可能地便携,例如它应该在linux、mac和win32环境下工作。我该如何做到这一点?

4

6 回答 6

20

Boost Filesystem Library 第 3 版提供unique_path()了生成适合创建临时文件或目录的路径名的功能。

using namespace boost::filesystem;

path ph = temp_directory_path() / unique_path();
create_directories(ph);
于 2011-05-13T07:37:12.807 回答
10

C++17 std::filesystem::temp_directory_path+ 随机数生成

这是一个可能可靠的纯 C++17 解决方案:没有 Boost 或其他外部库,也mkdtemp没有POSIX

我们只是循环随机数,直到我们能够创建一个以前不存在的目录std::filesystem::temp_directory_path/tmp在 Ubuntu 18.04 中)。

然后,我们可以在完成后显式删除创建的目录std::filesystem::remove_all

我不确定 C++ 标准是否能保证这一点,但极有可能std::filesystem::temp_directory_path调用mkdir,它以原子方式尝试创建目录,如果它不能失败EEXIST,所以我认为并行调用者之间不会存在竞争条件。

主文件

#include <exception>
#include <fstream>
#include <iostream>
#include <random>
#include <sstream>

#include <filesystem>

std::filesystem::path create_temporary_directory(
      unsigned long long max_tries = 1000) {
    auto tmp_dir = std::filesystem::temp_directory_path();
    unsigned long long i = 0;
    std::random_device dev;
    std::mt19937 prng(dev());
    std::uniform_int_distribution<uint64_t> rand(0);
    std::filesystem::path path;
    while (true) {
        std::stringstream ss;
        ss << std::hex << rand(prng);
        path = tmp_dir / ss.str();
        // true if the directory was created.
        if (std::filesystem::create_directory(path)) {
            break;
        }
        if (i == max_tries) {
            throw std::runtime_error("could not find non-existing directory");
        }
        i++;
    }
    return path;
}

int main() {
    auto tmpdir = create_temporary_directory();
    std::cout << "create_temporary_directory() = "
              << tmpdir
              << std::endl;

    // Use our temporary directory: create a file
    // in it and write to it.
    std::ofstream ofs(tmpdir / "myfile");
    ofs << "asdf\nqwer\n";
    ofs.close();

    // Remove the directory and its contents.
    std::filesystem::remove_all(tmpdir);
}

GitHub 上游.

编译并运行:

g++-8 -std=c++17 -Wall -Wextra -pedantic -o main.out main.cpp -lstdc++fs
./main.out

样本输出:

_directory.out
temp_directory_path() = "/tmp"
create_temporary_directory() = "/tmp/106adc08ff89874c"

有关文件,请参阅:如何在 C++ 中创建临时文本文件?文件有点不同,因为open在 Linux 中有O_TMPFILE,它创建了一个匿名 inode,在 close 时自动消失,因此专用的临时文件 API 可以通过使用它来提高效率。然而,没有类似的标志mkdir,所以这个解决方案可能是最优的。

在 Ubuntu 18.04 中测试。

于 2019-10-18T16:36:10.070 回答
6

检查这里mkdtemp的功能。

于 2010-07-31T22:12:38.540 回答
1

Boost 的 Filesystem 库提供了与平台无关的目录功能。它会稍微增加你的程序大小,但使用 Boost 通常比滚动你自己的更好(而且通常更容易)。

http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm

于 2010-08-01T03:08:31.547 回答
0

mkdtemp(char *template)

http://www.cl.cam.ac.uk/cgi-bin/manpage?3+mkdtemp

创建一个临时目录。

于 2010-07-31T22:07:54.727 回答
0

没有标准函数可以执行此操作,因此您需要为每个目标平台编译不同的实现。

例如,在 Windows 上,您应该使用 temp 目录,该目录可以通过调用 GetTempPath() 获得。

于 2010-08-01T02:59:47.350 回答