Necesito crear un nuevo identificador de archivo para que cualquier operación de escritura en ese manipulador se escriba en el disco inmediatamente.Win32: ¿Escribir en el archivo sin almacenamiento en búfer?
Información adicional: El identificador heredado es heredado de un proceso hijo, por lo que necesito que cualquier resultado de ese proceso se escriba inmediatamente en el disco.
El estudio de la documentación CreateFile
, la bandera FILE_FLAG_WRITE_THROUGH
parecía exactamente lo que necesito:
operaciones de escritura no van a ir a través de cualquier caché intermedio, van a ir directamente en el disco.
Escribí un programa de prueba muy básico y, bueno, no está funcionando. Utilicé la bandera en CreateFile y usé WriteFile(myHandle,...)
en un ciclo largo, escribiendo aproximadamente 100 MB de datos en aproximadamente 15 segundos. (Agregué algunos Sleep()
).
Luego configuré un entorno de supervisión profesional que consiste en presionar continuamente 'F5' en el explorador. Los resultados: el archivo permanece en 0kB y luego salta a 100MB aproximadamente al momento en que finaliza el programa de prueba.
Lo siguiente que probé fue enjuagar manualmente el archivo después de cada escritura, con FlushFileBuffers(myHandle)
. Esto hace que el tamaño del archivo observado crezca agradable y estable, como se esperaba.
Mi pregunta es, entonces, ¿no debería el FILE_FLAG_WRITE_THROUGH
haber hecho esto sin enjuagando manualmente el archivo? ¿Me estoy perdiendo de algo? En el programa 'mundo real', no puedo vaciar el archivo, porque no tengo ningún control sobre el proceso secundario que lo está usando.
También existe el indicador FILE_FLAG_NO_BUFFERING
, que no puedo usar por la misma razón: no tengo control sobre el proceso que está usando el identificador, por lo que no puedo alinear manualmente las escrituras como lo requiere esta bandera.
EDIT: He hecho un proyecto separado específicamente para ver cómo cambia el tamaño del archivo. Utiliza la clase .NET FileSystemWatcher
. También escribo menos datos, alrededor de 100kB en total.
Aquí está la salida. Mira los segundos en las marcas de tiempo.
El 'orden interna no-buffers' versión:
25.11.2008 7:03:22 PM: 10230 bytes added.
25.11.2008 7:03:31 PM: 10240 bytes added.
25.11.2008 7:03:31 PM: 10240 bytes added.
25.11.2008 7:03:31 PM: 10240 bytes added.
25.11.2008 7:03:31 PM: 10200 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10240 bytes added.
25.11.2008 7:03:42 PM: 10190 bytes added.
... y el 'forzada (manual) a ras' versión (FlushFileBuffers()
se llama cada ~ 2,5 segundos):
25.11.2008 7:06:10 PM: 10230 bytes added.
25.11.2008 7:06:12 PM: 10230 bytes added.
25.11.2008 7:06:15 PM: 10230 bytes added.
25.11.2008 7:06:17 PM: 10230 bytes added.
25.11.2008 7:06:19 PM: 10230 bytes added.
25.11.2008 7:06:21 PM: 10230 bytes added.
25.11.2008 7:06:23 PM: 10230 bytes added.
25.11.2008 7:06:25 PM: 10230 bytes added.
25.11.2008 7:06:27 PM: 10230 bytes added.
25.11.2008 7:06:29 PM: 10230 bytes added.
¿Por qué cree que necesita esto? – Tim
+1 para el 'profesional Explorer + F5'. Pero tengo que recordarle que la visibilidad dentro del mismo sistema operativo no significa el 'lavado/durabilidad'. Debe actuar de manera más profesional: reinicie la PC o extraiga en caliente la unidad de disco duro del sistema. No estoy seguro de que el reinicio o apagado no inicie el enjuague de la memoria caché integrada. Solo si retira la unidad físicamente o utiliza algún almacenamiento falso, puede estar seguro de que la descarga ha llegado efectivamente al dispositivo. – Val
@RecognizeEvilasWaste hmm ... veamos si wor –