2009-01-24 10 views
14

¿Hay alguna manera de aprovechar los indicadores de creación de archivos en la API de Win32 como FILE_FLAG_DELETE_ON_CLOSE o FILE_FLAG_WRITE_THROUGH como se describe aquí http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx, pero luego forzar ese identificador a std :: ofstream?¿Puedo usar CreateFile, pero forzar el handle en std :: ofstream?

La interfaz de ofstream es obviamente independiente de la plataforma; Me gustaría forzar algunas configuraciones dependientes de la plataforma en 'bajo el capó' como estaban.

Respuesta

24

Es posible adjuntar un C++ std::ofstream a un controlador de archivo de Windows. El siguiente código funciona en VS2008:

HANDLE file_handle = CreateFile(
    file_name, GENERIC_WRITE, 
    0, NULL, CREATE_ALWAYS, 
    FILE_ATTRIBUTE_NORMAL, NULL); 

if (file_handle != INVALID_HANDLE_VALUE) { 
    int file_descriptor = _open_osfhandle((intptr_t)file_handle, 0); 

    if (file_descriptor != -1) { 
     FILE* file = _fdopen(file_descriptor, "w"); 

     if (file != NULL) { 
      std::ofstream stream(file); 

      stream << "Hello World\n"; 

      // Closes stream, file, file_descriptor, and file_handle. 
      stream.close(); 

      file = NULL; 
      file_descriptor = -1; 
      file_handle = INVALID_HANDLE_VALUE; 
     } 
} 

Esto funciona con FILE_FLAG_DELETE_ON_CLOSE, pero FILE_FLAG_WRITE_THROUGH pueden no tener el efecto deseado, ya que los datos serán amortiguados por el objeto std::ofstream, y no se puede escribir directamente en el disco. Sin embargo, cualquier dato en el búfer se descargará al SO cuando se llame al stream.close().

+0

Excelente (¡también funciona en VS2005)! Una situación que tengo es la de escribir cierta información de contabilidad en un archivo en un USB con escritura directa. Como se tratará de una secuencia rápida de escritura-cierre-cierre, la llamada para cerrar debería garantizar que el buffer de corriente se descargue al sistema operativo, ¿no? –

+0

Sí. He actualizado la respuesta para mencionar esto. – ChrisN

+0

¿Alguna idea sobre cómo hacer lo mismo para 'fstream' en lugar de' ofstream'? – sorin

1

Algunas de estas opciones también están disponibles cuando se utiliza _fsopen/fopen:

FILE* pLockFile = _fsopen(tmpfilename.c_str(), "w", _SH_DENYWR); 
if (pLockFile!=NULL 
{ 
    // Write lock aquired 
    ofstream fs(pLockFile); 
} 

Aquí abrimos el archivo para cuando se hace un color, entonces se escribe a través de (Y se elimina cuando se cierra):

FILE* pCommitFile = fopen(tmpfilename.c_str(), "wcD"); 
if (pCommitFile!=NULL) 
{ 
    // Commits when doing flush 
    ofstream fs(pCommitFile); 
} 
Cuestiones relacionadas