es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Antes de cerrar el archivo en el destructor de la clase File (C++), realizad el vaciado y sincronización.

Como ejercicio, quiero escribir una clase que describa un archivo que contiene bloques de datos. Dentro del destructor de la clase simplemente llamé a close, ya que (citando de http://www.cplusplus.com/doc/tutorial/files/)

Cuando el búfer se vacía, todos los datos contenidos en él se escriben en el medio físico (si es una secuencia de salida). Este proceso se llama sincronización y ocurre bajo alguna de las siguientes circunstancias:
Cuando el archivo se cierra: antes de cerrar un archivo, se sincronizan todos los búferes que aún no se han vaciado y se escriben o leen todos los datos pendientes en el medio físico.

A continuación se muestra un código de ejemplo.


<h1>pragma once</h1> <h1>include <filesystem></h1> <h1>include <fstream></h1> <h1>include <string></h1> namespace fs = std::filesystem; template<class block=""> class BlockFile { private: fs::path mFilePath; std::fstream mFile; public: BlockFile(fs::path fPath) : mFilePath{fPath} { // esto está mal por muchos motivos (el archivo puede existir, no es seguro para subprocesos, etc.), pero de todos modos auto touch = ofstream{mFilePath}; } ~BlockFile() { mFile.close(); } // métodos de lectura, escritura, agregado, etc. };

Sin embargo, cuando leí otra solución, el destructor estaba implementado de la siguiente manera


~BlockFile()
{
mFile.flush();
mFile.sync();
mFile.close();
}

Mi pregunta principal es por qué necesitamos vaciar y sincronizar explícitamente, ya que la cita anterior dice que se hace antes de cerrar el archivo?

Pregunta adicional: En la respuesta aceptada de esta pregunta https://stackoverflow.com/questions/14251873/what-is-the-difference-between-flush-and-sync-in-regard-to-fstream-buffers se menciona

basic_ostream::flush Esto es una función no virtual que escribe los cambios no confirmados en el búfer subyacente. En caso de error, establece una bandera de error en el objeto de secuencia utilizado. Esto se debe a que el valor de retorno es una referencia a la propia secuencia, para permitir el encadenamiento.

basic_filebuf::sync Esto es una función virtual que escribe todos los cambios pendientes en el archivo subyacente y devuelve un código de error para indicar el éxito o el fracaso.

¿Cuál es la diferencia entre cambios no confirmados y cambios pendientes?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La razón por la cual necesitamos explícitamente hacer flush y sync del archivo antes de cerrarlo es porque puede haber datos que aún no se han escrito en el medio físico en el buffer. Llamar a close por sí solo solamente sincroniza y hace flush de todos los buffers que aún no han sido vaciados. Sin embargo, es posible que aún existan cambios pendientes en el buffer que no han sido confirmados en el flujo. Es por eso que necesitamos llamar a flush para escribir los cambios no confirmados en el buffer subyacente y sync para escribir todos los cambios pendientes en el archivo subyacente antes de cerrar el archivo.

    En cuanto a la pregunta adicional, “cambios no confirmados” se refiere a los cambios que se han realizado en el flujo pero que aún no se han escrito en el buffer subyacente, mientras que “cambios pendientes” se refiere a los cambios que se han realizado en el buffer subyacente pero que aún no se han escrito en el medio físico. Llamar a flush escribe los cambios no confirmados en el buffer subyacente, mientras que llamar a sync escribe todos los cambios pendientes en el archivo subyacente.

Comments are closed.