Verze 3 knihovny Boost Filesystem Library poskytuje funkci unique_path()
pro generování názvu cesty vhodného pro vytvoření dočasného souboru nebo adresáře.
using namespace boost::filesystem;
path ph = temp_directory_path() / unique_path();
create_directories(ph);
C++17 std::filesystem::temp_directory_path
+ generování náhodných čísel
Zde je čisté řešení C++17, které může být spolehlivé:žádné Boost nebo jiné externí knihovny a žádné mkdtemp
což je POSIX.
Jen procházíme náhodnými čísly, dokud nebudeme schopni vytvořit adresář, který dříve neexistoval uvnitř std::filesystem::temp_directory_path
(/tmp
v Ubuntu 18.04).
Vytvořený adresář pak můžeme explicitně odstranit pomocí std::filesystem::remove_all
až s tím skončíme.
Nejsem si jistý, zda to standard C++ zaručuje, ale je velmi pravděpodobné, že std::filesystem::temp_directory_path
volání mkdir
, který se atomicky pokusí vytvořit adresář a pokud to nejde, selže s EEXIST
, takže si nemyslím, že mezi paralelními volajícími mohou existovat závodní podmínky.
main.cpp
#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 upstream.
Kompilace a spuštění:
g++-8 -std=c++17 -Wall -Wextra -pedantic -o main.out main.cpp -lstdc++fs
./main.out
Ukázkový výstup:
_directory.out
temp_directory_path() = "/tmp"
create_temporary_directory() = "/tmp/106adc08ff89874c"
Soubory viz:Jak vytvořit dočasný textový soubor v C++? Soubory jsou trochu jiné, protože open
v Linuxu má O_TMPFILE
, který vytvoří anonymní inode, který automaticky zmizí při zavření, takže vyhrazená rozhraní API pro dočasné soubory mohou být díky tomu efektivnější. Pro mkdir
neexistuje žádný analogický příznak toto řešení však může být optimální.
Testováno v Ubuntu 18.04.
Knihovna souborového systému Boost poskytuje adresářové funkce nezávislé na platformě. Trochu to zvětší velikost vašeho programu, ale použití Boost je často lepší (a často snazší) než spouštění vlastního.
http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm
Zkontrolujte mkdtemp
funkce zde.