sintaxis read para librerías libreria leer fichero escribir enteros ejemplos ejemplo crear como archivos archivo c++ file file-io mkstemp

read - ofstream c++ ejemplos



¿Cómo crear un std:: ofstream en un archivo temporal? (4)

Creo que esto debería funcionar:

char *tmpname = strdup("/tmp/tmpfileXXXXXX"); ofstream f; int fd = mkstemp(tmpname); f.attach(fd);

EDITAR: Bueno, esto podría no ser portátil. Si no puede usar attach y no puede crear un flujo de corriente directamente desde un descriptor de archivo, entonces tiene que hacer esto:

char *tmpname = strdup("/tmp/tmpfileXXXXXX"); mkstemp(tmpname); ofstream f(tmpname);

Como mkstemp ya crea el archivo para usted, la condición de carrera no debería ser un problema aquí.

De acuerdo, mkstemp es la forma preferida de crear un archivo temporal en POSIX.

Pero abre el archivo y devuelve un int , que es un descriptor de archivo. De eso solo puedo crear un ARCHIVO *, pero no un std::ofstream , que preferiría en C ++. (Aparentemente, en AIX y algunos otros sistemas, puede crear un std::ofstream desde un descriptor de archivo, pero mi compilador se queja cuando lo intento).

Sé que podría obtener un nombre de archivo temporal con tmpnam y luego abrir mi propio flujo de corriente con él, pero aparentemente no es seguro debido a las condiciones de carrera, y da como resultado una advertencia de compilación (g ++ v3.4. En Linux):

warning: the use of `tmpnam'' is dangerous, better use `mkstemp''

Entonces, ¿hay alguna forma portátil de crear un std::ofstream en un archivo temporal?


He hecho esta función:

#include <stdlib.h> #include <fstream> #include <iostream> #include <vector> std::string open_temp(std::string path, std::ofstream& f) { path += "/XXXXXX"; std::vector<char> dst_path(path.begin(), path.end()); dst_path.push_back(''/0''); int fd = mkstemp(&dst_path[0]); if(fd != -1) { path.assign(dst_path.begin(), dst_path.end() - 1); f.open(path.c_str(), std::ios_base::trunc | std::ios_base::out); close(fd); } return path; } int main() { std::ofstream logfile; open_temp("/tmp", logfile); if(logfile.is_open()) { logfile << "hello, dude" << std::endl; } }

Probablemente deberías asegurarte de llamar a umask con una máscara de creación de archivo adecuada (preferiría 0600): la página de manual para mkstemp dice que la máscara de creación de modo de archivo no está estandarizada. Utiliza el hecho de que mkstemp modifica su argumento para el nombre de archivo que usa. Entonces, lo abrimos y cerramos el archivo que se abrió (para que no se haya abierto dos veces), quedando con un flujo de corriente que está conectado a ese archivo.


Quizás esto funcione:

char tmpname[256]; ofstream f; sprintf (tmpname, "/tmp/tmpfileXXXXXX"); int fd = mkstemp(tmpname); ofstream f(tmpname);

No lo he intentado, pero puedes verificarlo.


char tempFileName[20]; // name only valid till next invocation of tempFileOpen ofstream tempFile; void tempFileOpen() { strcpy(tempFileName, "/tmp/XXXXXX"); mkstemp(tempFileName); tempFile.open(tempFileName); }

Este código funciona para mí con GCC / libstdc ++ 6 4.8.4 y Clang 3.9 también. Gracias a las otras respuestas que fueron útiles para mí.