2010-03-01 12 views
14

He notado un gran impacto en el rendimiento en uno de mis proyectos cuando el registro está habilitado por primera vez. Pero cuando se alcanza el límite del archivo de registro y el programa comienza a escribir nuevamente al comienzo del archivo, la velocidad de registro es mucho más rápida (aproximadamente un 50% más rápida). Es normal establecer el tamaño del archivo de registro en cientos de MB.Reserve el espacio en disco antes de escribir un archivo para la eficacia

La mayoría de los administradores de descargas asignan el archivo ficticio con el tamaño requerido antes de comenzar a descargar el archivo. Esto hace que la escritura sea más eficaz porque todo el fragmento se asigna a la vez.

¿Cuál es la mejor manera de reservar espacio en disco de manera eficiente, con un tamaño fijo, cuando mi programa se inicia por primera vez?

+0

Esta es una pregunta de Windows, no una pregunta de C++. Es una cuestión de la API de Windows en lugar de cómo llamarlo con un programa C++. Sugeriría eliminar la etiqueta C++; hay muchos tipos de .NET por aquí que saben qué buscar. –

+0

Posible duplicado de [¿Cómo preasigna espacio para un archivo en C/C++ en Windows?] (Https://stackoverflow.com/questions/7970333/how-do-you-pre-allocate-space-for- a-file-in-cc-on-windows) –

+1

¿Por qué no puede simplemente crear un registro vacío con cualquier tamaño que desee? – wRAR

Respuesta

8
void ReserveSpace(LONG spaceLow, LONG spaceHigh, HANDLE hFile) 
{ 
    DWORD err = ::SetFilePointer(hFile, spaceLow, &spaceHigh, FILE_BEGIN); 

    if (err == INVALID_SET_FILE_POINTER) { 
     err = GetLastError(); 
     // handle error 
    } 
    if (!::SetEndOfFile(hFile)) { 
     err = GetLastError(); 
     // handle error 
    } 
    err = ::SetFilePointer(hFile, 0, 0, FILE_BEGIN); // reset 
} 
+0

Gracias. Eso es exactamente lo que quería. – haggag

4

wRAR es correcto. Abre un nuevo archivo usando tu biblioteca favorita, luego busca el penúltimo byte y escribe un 0 allí. Eso debería asignar todo el espacio de disco requerido.

+0

¿Es verdad? Siempre pensé que NTFS admite agujeros de archivos, pero no puedo encontrar una fuente para eso en este momento. – dmeister

+1

"La mayoría de las aplicaciones no conocen los archivos dispersos y no crearán archivos dispersos. El hecho de que una aplicación lea un archivo disperso es transparente para la aplicación. Una aplicación que tenga en cuenta los archivos dispersos debe determinar si su conjunto de datos es adecuado. que se mantendrá en un archivo disperso. Después de que se realiza la determinación, la aplicación debe declarar explícitamente un archivo como disperso, utilizando el código de control FSCTL_SET_SPARSE ". – wRAR

+1

Como wRAR implica, NTFS admite agujeros de archivos, pero debe crearlo explícitamente con FSCTL_SET_SPARSE o configurando el archivo para que se comprima. – Gabe

0

Aquí es una función simple que funcionará para archivos de cualquier tamaño:

void SetFileSize(HANDLE hFile, LARGE_INTEGER size) 
{ 
    SetFilePointer(hFile, size, NULL, FILE_BEGIN); 
    SetEndOfFile(hFile); 
} 
+1

Es posible que desee volver a establecer el puntero al principio –

0

Usted puede utilizar la función SetFileValidData para extender la longitud lógica de un archivo sin tener que escribir todos esos datos a disco. Sin embargo, dado que puede permitir la lectura de datos de disco a los que de otra manera no habría tenido privilegios, se requiere el privilegio SE_MANAGE_VOLUME_NAME. Lea atentamente la sección Observaciones de la documentación.

También la implementación de SetFileValidData depende del controlador fs. NTFS lo admite y FAT solo desde Win7.

Cuestiones relacionadas