perché Fsutil.exe richiede meno tempo per scrivere un file enorme in disco rispetto di programmazione?

StackOverflow https://stackoverflow.com/questions/1893200

  •  19-09-2019
  •  | 
  •  

Domanda

questa domanda è in base a questo argomento: la creazione di un file fittizio enorme in una questione di secondi in c #

Ho appena controllato il Fsutil.exe in XP / Vista / Seven a dare una quantità enorme di dati fittizi in disco di archiviazione e ci vuole meno tempo per scrivere un file di grandi dimensioni come in confronto a programmaticly modo.

Quando sto cercando di fare la stessa cosa con l'aiuto di .NET ci vorrà molto più tempo di quanto Fsutil.exe.

Nota: So che .net non utilizzare codice nativo a causa di questo ho appena controllato la questione con API native di troppo come segue:

long int size = DiskFree('L' - 64);
const char* full = "fulldisk.dsk";
__try{
Application->ProcessMessages();
HANDLE hf = CreateFile(full,
                       GENERIC_WRITE,
                       0,
                       0,
                       CREATE_ALWAYS,
                       0,
                       0);
SetFilePointer(hf, size, 0, FILE_BEGIN);
SetEndOfFile(hf);
CloseHandle(hf);
}__finally{
    ShowMessage("Finished");
    exit(0);

e la risposta fu più uguale risultati .net.

, ma con l'aiuto di Fsutil.exe ci vuole solo meno della durata di sopra o al di approcci .net dire che è 2 volte più veloce

Esempio: per la scrittura di 400MB con .net ci vorrà ~ 40 secondi la stessa quantità con Fsutil.exe vorranno circa 20secs o meno.

v'è alcuna spiegazione in proposito? o quale funzione Fsutil.exe fa uso che ha questa velocità significato per scrivere?

È stato utile?

Soluzione

Non so esattamente cosa fsutil sta facendo, ma so di due modi di scrivere un file di grandi dimensioni che sono più veloce di quello che hai fatto in precedenza (o cercano di lunghezza che si desidera e la scrittura di uno zero, che ha lo stesso risultato).

Il problema con questi approcci è che lo zero-riempiono il file al momento di fare la scrittura.

È possibile evitare il riempimento zero o:

  1. La creazione di un file sparse. La dimensione è segnato nel punto desiderato, ma i dati in realtà non esiste sul disco fino a quando si scrive. Tutte le letture delle aree non scritte tornerà zeri.
  2. Uso della SetFileValidData funzione impostare la lunghezza dei dati validi senza azzerare il file prima. Tuttavia, a causa di problemi di sicurezza potenziali, questo comando richiede autorizzazioni elevate.

Altri suggerimenti

Sono d'accordo con l'ultimo commento. Stavo sperimentando con un driver mini-filtro ed è stato catturando IRP_MJ_WRITE IRP in callback. Quando ho creare o scrivere il file dalla linea di cmd o applicazione win32, riesco a vedere le scritture scendendo. Ma quando ho creato un file usando "File createnew fsutil ..." di comando, non vedo alcun scrittura. Sto vedendo questo comportamento su win2k8 R2 sul volume NTFS. E non credo (non sono sicuro al 100% però) si tratta di un file sparse sia. Probabilmente è l'impostazione delle proprietà dimensioni in MFT senza allocare alcun cluster. fsutil fare controllare lo spazio libero disponibile, quindi se la dimensione del file è più grande di spazio libero su disco, si ottiene l'errore 1.

Inoltre ho fatto funzionare FSCTL_GET_RETRIEVAL_POINTERS programma Sening al file e ho ottenuto una misura per l'intera dimensione del file. Ma io credo che sta ottenendo tutti i dati

Questa è una cosa che potrebbe essere

  • Scritto in Assembler (velocità accecante Raw)
  • A Native C / C ++ di codice per fare questo
  • Possibilmente una chiamata di sistema non documentato per fare questo o qualche trucco che non è documentato da nessuna parte.

Le suddette tre punti potrebbero avere un fattore significativo enorme - quando si pensa a questo proposito, quando viene caricato un codice .NET, si ottiene jit'ted dal runtime (Ok, il fattore tempo non sarebbe evidente se si dispone di un velocissimo macchina -. su un Pentium fine umile, sarebbe evidente, il caricamento lento)

Più che probabile che avrebbe potuto essere scritto in C / C ++. Può sorprendere, se è stato scritto in Assembler.

È possibile controllare questo per te - guardare la dimensione del file dell'eseguibile e confrontarlo con un eseguibile di .NET. Si potrebbe obiettare che il file è compresso, cosa di cui dubito che sarebbe stato e quindi incline a escludere questo caso, Microsoft non sarebbe andato così lontano mi sa con la compressione di business eseguibili.

Spero che questo risponde alla tua domanda, I migliori saluti, Tom.

fsutil è solo veloce su NTFS e exFAT, non su FAT32, FAT16 Questo perché alcuni file system hanno un concespt "dimensione inizializzata", e quindi sostenere l'inizializzazione veloce di file. Questo riserva solo i grappoli, ma non li zero fuori, perché si nota nel file system che nessun dato è stato scritto nel file e validi legge sarebbero tutti tornare 00-riempite buffer.

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