La mejor solución es implementar una escritura asíncrona con doble búfer.
Mira la línea de tiempo:
------------------------------------------------>
FF|WWWWWWWW|FF|WWWWWWWW|FF|WWWWWWWW|FF|WWWWWWWW|
La 'F' representa el tiempo para llenar el búfer y la 'W' representa el tiempo para escribir el búfer en el disco. Entonces, el problema es perder el tiempo entre escribir buffers para archivar. Sin embargo, al implementar la escritura en un hilo separado, puede comenzar a llenar el siguiente búfer de inmediato de esta manera:
------------------------------------------------> (main thread, fills buffers)
FF|ff______|FF______|ff______|________|
------------------------------------------------> (writer thread)
|WWWWWWWW|wwwwwwww|WWWWWWWW|wwwwwwww|
F - llenado del 1er búfer
f - llenado del 2o búfer
W - escritura del 1er búfer en el archivo
w - escritura del 2o búfer en el archivo
_ - espere mientras se completa la operación
Este enfoque con intercambios de búfer es muy útil cuando llenar un búfer requiere un cálculo más complejo (por lo tanto, más tiempo). Siempre implemento una clase CSequentialStreamWriter que oculta la escritura asincrónica en el interior, por lo que para el usuario final la interfaz solo tiene funciones de escritura.
Y el tamaño del búfer debe ser un múltiplo del tamaño del clúster de disco. De lo contrario, terminará con un rendimiento deficiente escribiendo un único búfer en 2 grupos de discos adyacentes.
Escribiendo el último búfer.
Cuando llama a la función Escribir por última vez, debe asegurarse de que el búfer actual se esté llenando también debe escribirse en el disco. Por lo tanto, CSequentialStreamWriter debería tener un método separado, digamos Finalizar (descarga de búfer final), que debería escribir en el disco la última porción de datos.
Manejo de errores.
Mientras que el código comienza a llenar el segundo búfer, y el primero se está escribiendo en un hilo separado, pero la escritura falla por alguna razón, el hilo principal debe ser consciente de ese error.
------------------------------------------------> (main thread, fills buffers)
FF|fX|
------------------------------------------------> (writer thread)
__|X|
Supongamos que la interfaz de un CSequentialStreamWriter tiene una función Write que devuelve bool o lanza una excepción, por lo tanto, al tener un error en un hilo separado, debe recordar ese estado, por lo que la próxima vez que llame a Write o Finilize en el hilo principal, el método devolverá Falso o arrojará una excepción. Y realmente no importa en qué punto dejaste de llenar un búfer, incluso si escribiste algunos datos después del error, lo más probable es que el archivo esté dañado e inútil.