Domanda

Sto usando VB6 e l'API Win32 per scrivere i dati in un file, questa funzionalità è per l'esportazione dei dati, quindi scrivere le prestazioni sul disco è il fattore chiave nelle mie considerazioni. Come tale sto usando le opzioni FILE_FLAG_NO_BUFFERING e FILE_FLAG_WRITE_THROUGH quando apro il file con una chiamata a CreateFile .

FILE_FLAG_NO_BUFFERING richiede che io usi il mio buffer e scriva i dati nel file in multipli delle dimensioni del settore del disco, questo non è un problema in generale, a parte l'ultima parte dei dati, che se è non un multiplo esatto della dimensione del settore includerà il riempimento del carattere zero del file, come posso impostare la dimensione del file una volta che l'ultimo blocco è stato scritto per non includere questi zero del carattere?

Posso usare SetEndOfFile ma questo mi richiede di chiudere il file e riaprirlo senza usare FILE_FLAG_NO_BUFFERING . Ho visto qualcuno parlare di NtSetInformationFile ma non riesco a trovare come usare e dichiararlo in VB6. SetFileInformationByHandle può fare esattamente quello che voglio, tuttavia è disponibile solo in Windows Vista, la mia applicazione deve essere compatibile con le versioni precedenti di Windows.

È stato utile?

Soluzione

Non sono sicuro, ma SEI sicuro che l'impostazione FILE_FLAG_NO_BUFFERING e FILE_FLAG_WRITE_THROUGH ti offrono le massime prestazioni?

Certamente i tuoi dati verranno colpiti il ??più presto possibile sul disco, ma quel genere di cose non aiuta le prestazioni, ma solo l'affidabilità per cose come i file journal che vuoi essere il più completo possibile in l'evento di un incidente.

Per una routine di esportazione dei dati come descritta, consentire al sistema operativo di bufferizzare i dati porterà probabilmente a MIGLIORI prestazioni, poiché le scritture verranno pianificate in linea con altre attività del disco, piuttosto che forzare il disco a tornare al file ogni scrittura.

Perché non esegui il benchmarking del tuo codice senza quelle opzioni? Lascia nella logica di padding a 0 byte per renderlo un test corretto.

Se si scopre che saltare queste opzioni è più veloce, è possibile rimuovere la logica di riempimento 0 e il problema relativo alle dimensioni del file si risolve da solo.

Altri suggerimenti

Credo che SetEndOfFile sia l'unico modo.

E sono d'accordo con Mike G. che dovresti mettere in panchina il tuo codice con e senza FILE_FLAG_NO_BUFFERING. Il buffering dei file di Windows sui moderni sistemi operativi è dannatamente efficace.

Beh, sono stupito! Usare il buffering di Windows invece di fare tutto da solo è MOLTO più veloce. Ho scritto un file da 1 GB con cui testare, usando il mio buffer e le opzioni FILE_FLAG_NO_BUFFERING e FILE_FLAG_WRITE_THROUGH sono durate in media 21.146 secondi, senza quelle impostazioni e usando il buffer di Windows il tempo medio è sceso a 13,53 secondi, ovvero oltre il 30% più veloce!

Nota per sé: non è necessario reinventare la ruota. ; -)

Grazie ' Mike G ' per la tua risposta rapida e accurata. E grazie anche a te " gabr ", non devi preoccuparti di SetEndOfFile adesso.

Per un file da 1 GB, probabilmente il buffering di Windows sarà probabilmente più veloce, esp. se sta facendo molti piccoli IO. Se hai a che fare con file molto più grandi della RAM disponibile e stai eseguendo IO a blocchi di grandi dimensioni, i flag che stavi impostando produrranno un throughput migliore (fino a 3 volte più veloce per IO a blocchi di grandi dimensioni con thread pesante e / o casuale).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top