2010-03-01 11 views
14

Ho notato un enorme successo in uno dei miei progetti quando la registrazione è abilitata per la prima volta. Ma quando viene raggiunto il limite del file di registro e il programma inizia a scrivere nuovamente all'inizio del file, la velocità di registrazione è molto più veloce (circa il 50% più veloce). È normale impostare le dimensioni del file di registro su centinaia di MB.Prenotare spazio su disco prima di scrivere un file per l'efficienza

La maggior parte dei gestori di download allocano un file fittizio con la dimensione richiesta prima di iniziare a scaricare il file. Ciò rende la scrittura più efficace perché l'intero blocco viene assegnato contemporaneamente.

Qual è il modo migliore per prenotare lo spazio su disco in modo efficiente, da qualche dimensione fissa, quando il mio programma si avvia per la prima volta?

+0

Questa è una domanda di Windows, non una domanda in C++. È una questione dell'API di Windows piuttosto che come chiamarla con un programma C++. Suggerirei di rimuovere il tag C++; c'è un sacco di tipi .NET qui intorno che sanno cosa cercare. –

+0

Possibile duplicato di [Come si pre-alloca spazio per un file in C/C++ su Windows?] (Https://stackoverflow.com/questions/7970333/how-do-you-pre-allocate-space-for- a-file-in-cc-on-windows) –

+1

Perché non puoi semplicemente creare un log vuoto usando qualsiasi dimensione tu voglia? – wRAR

risposta

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

Grazie. Questo è esattamente quello che volevo. – haggag

4

wRAR è corretto. Apri un nuovo file usando la tua libreria preferita, quindi cerca il penultimo byte e scrivi uno 0 lì. Questo dovrebbe allocare tutto lo spazio su disco richiesto.

+0

È vero? Ho sempre pensato che NTFS supporti i buchi dei file, ma al momento non riesco a trovare una fonte per questo. – dmeister

+1

"La maggior parte delle applicazioni non è a conoscenza di file sparsi e non creerà file sparsi Il fatto che un'applicazione stia leggendo un file sparse è trasparente per l'applicazione. Un'applicazione che è a conoscenza di file sparsi dovrebbe determinare se il suo set di dati è adatto da conservare in un file sparse. Dopo aver determinato tale definizione, l'applicazione deve dichiarare esplicitamente un file come sparse, utilizzando il codice di controllo FSCTL_SET_SPARSE. " – wRAR

+1

Come suggerisce wRAR, NTFS supporta i buchi dei file, ma è necessario crearlo esplicitamente con FSCTL_SET_SPARSE o impostando il file da comprimere. – Gabe

0

Ecco una semplice funzione che funziona per i file di qualsiasi dimensione:

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

È possibile impostare il puntatore del file all'inizio –

0

È possibile utilizzare la funzione SetFileValidData per estendere la lunghezza logica di un file senza dover scrivere tutti i dati a disco. Tuttavia, poiché può consentire di leggere i dati del disco a cui non si è altrimenti avuto il privilegio, richiede il privilegio SE_MANAGE_VOLUME_NAME da utilizzare. Leggere attentamente la sezione Note della documentazione.

Anche l'implementazione di SetFileValidData dipende dal driver fs. NTFS lo supporta e FAT solo da Win7.

Problemi correlati