Pregunta

Estoy usando VB6 y la API Win32 para escribir datos en un archivo, esta funcionalidad es para la exportación de datos, por lo tanto, el rendimiento de escritura en el disco es el factor clave en mis consideraciones. Como tal, estoy usando las opciones FILE_FLAG_NO_BUFFERING y FILE_FLAG_WRITE_THROUGH al abrir el archivo con una llamada a CreateFile .

FILE_FLAG_NO_BUFFERING requiere que use mi propio búfer y escriba datos en el archivo en múltiplos del tamaño del sector del disco, esto no es un problema en general, aparte de la última parte de los datos, que si es no un múltiplo exacto del tamaño del sector incluirá el carácter cero rellenando el archivo, ¿cómo configuro el tamaño del archivo una vez que se escribe el último bloque para no incluir estos caracteres cero?

Puedo usar SetEndOfFile sin embargo, esto requiere que cierre el archivo y lo abra de nuevo sin usar FILE_FLAG_NO_BUFFERING . He visto a alguien hablar sobre NtSetInformationFile , pero no puedo encontrar cómo usarlo y declararlo en VB6. SetFileInformationByHandle puede hacer exactamente lo que quiero, sin embargo, solo está disponible en Windows Vista, mi aplicación debe ser compatible con versiones anteriores de Windows.

¿Fue útil?

Solución

No estoy seguro, pero ¿ESTÁS seguro de que la configuración FILE_FLAG_NO_BUFFERING y FILE_FLAG_WRITE_THROUGH te brinda el máximo rendimiento?

Ciertamente harán que sus datos lleguen al disco lo antes posible, pero ese tipo de cosas en realidad no ayuda al rendimiento, solo ayuda a la confiabilidad para cosas como archivos de diario que desea que estén lo más completos posible el evento de un accidente.

Para una rutina de exportación de datos como la que usted describe, permitir que el sistema operativo almacene sus datos en búfer probablemente dará como resultado un MEJOR rendimiento, ya que las escrituras se programarán de acuerdo con otra actividad del disco, en lugar de obligar al disco a saltar de nuevo a su archiva cada escritura.

¿Por qué no compara su código sin esas opciones? Deje la lógica de relleno de 0 bytes para que sea una prueba justa.

Si resulta que omitir esas opciones es más rápido, entonces puede eliminar la lógica de relleno 0, y su problema de tamaño de archivo se corrige solo.

Otros consejos

Creo que SetEndOfFile es la única manera.

Y estoy de acuerdo con Mike G. en que deberías acomodar tu código con y sin FILE_FLAG_NO_BUFFERING. El almacenamiento en búfer de archivos de Windows en los sistemas operativos modernos es bastante efectivo.

¡Pues estoy asombrado! Usar el búfer de Windows en lugar de hacerlo todo por mí mismo es MUCHO más rápido. He estado escribiendo un archivo de 1 Gb para probar, usando mi propio búfer y las opciones de FILE_FLAG_NO_BUFFERING y FILE_FLAG_WRITE_THROUGH tomaron un promedio de 21.146 segundos, sin esas configuraciones y utilizando el búfer de Windows el tiempo promedio se redujo a 13.53 segundos, ¡un 30% más rápido!

Nota personal: no es necesario reinventar la rueda. ;-)

Gracias ' Mike G ' por su respuesta rápida y precisa. Y gracias también a ti ' gabr ', no necesitas preocuparte por SetEndOfFile en absoluto ahora.

Para un archivo de 1 GB, el almacenamiento en búfer de Windows probablemente será más rápido, especialmente. si está haciendo muchas IO pequeñas. Si está tratando con archivos que son mucho más grandes que la RAM disponible, y está haciendo IO de bloque grande, los indicadores que estaba configurando PRODUCIRÁN deben tener un mejor rendimiento (hasta 3 veces más rápido para IO de bloque grande muy roscado y / o aleatorio).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top