GNU/Linux >> Linux Esercitazione >  >> Linux

Come creare una directory temporanea in C++?

La versione 3 di Boost Filesystem Library fornisce la funzione unique_path() per generare un nome di percorso adatto alla creazione di un file temporaneo o di una directory.

using namespace boost::filesystem;

path ph = temp_directory_path() / unique_path();
create_directories(ph);

C++17 std::filesystem::temp_directory_path + generazione di numeri casuali

Ecco una soluzione C++17 pura che potrebbe essere affidabile:niente Boost o altre librerie esterne e niente mkdtemp che è POSIX.

Ci limitiamo a ripetere numeri casuali finché non siamo in grado di creare una directory che prima non esisteva all'interno di std::filesystem::temp_directory_path (/tmp in Ubuntu 18.04).

Possiamo quindi rimuovere esplicitamente la directory creata con std::filesystem::remove_all dopo che avremo finito.

Non sono sicuro che lo standard C++ lo garantisca, ma è estremamente probabile che std::filesystem::temp_directory_path chiama mkdir , che tenta atomicamente di creare la directory e se non ci riesce fallisce con EEXIST , quindi non penso che possano esserci condizioni di competizione tra i chiamanti paralleli.

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 a monte.

Compila ed esegui:

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

Esempio di output:

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

Per i file, vedere:Come creare un file di testo temporaneo in C++? I file sono leggermente diversi perché open in Linux ha il O_TMPFILE , che crea un inode anonimo che scompare automaticamente alla chiusura, quindi le API di file temporanei dedicate possono essere più efficienti utilizzandolo. Non esiste un flag analogo per mkdir tuttavia, questa soluzione potrebbe essere ottimale.

Testato in Ubuntu 18.04.


La libreria Filesystem di Boost fornisce funzioni di directory indipendenti dalla piattaforma. Aumenterà un po' le dimensioni del tuo programma, ma l'utilizzo di Boost è spesso migliore (e spesso più facile) rispetto al rollare il tuo.

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


Controlla il mkdtemp funzione qui.


Linux
  1. Come creare un file temporaneo nello script della shell?

  2. Come creare un file e montarlo come filesystem?

  3. Come creare snapshot del filesystem utilizzando Snapper Command su Linux

  4. Come creare filesystem ZFS con compressione file su Linux

  5. Come creare un filesystem tmpfs in CentOS/RHEL

Come utilizzare il comando mkdir per creare o creare una directory Linux

Come creare directory in Linux (comando mkdir)

Come creare una directory in Linux usando il comando mkdir

Come creare un filesystem XFS

Come creare/aggiungere utenti in Linux

Come creare comandi personalizzati in Unix/Linux?