2009-10-28 8 views
11

Quando si salva un file su una USB nella mia applicazione delphi, come posso assicurarmi che il file sia realmente (permanentemente) salvato su USB, quando "Rimozione sicura dell'hardware" non viene eseguito (specialmente dimenticato da usare)?
Dire al nostro cliente di utilizzare la funzionalità di Windows "Rimozione sicura dell'hardware" non funziona.
Esiste un comando API di Windows per svuotare il buffer, in modo che tutti i dati vengano scritti sull'unità USB in modo permanente?Come assicurarsi che un file sia stato salvato in modo permanente su USB, quando l'utente non usa "Rimozione sicura dell'hardware"?

+7

A chiunque abbia votato per chiudere come "Non programmazione correlata", rileggere la domanda. –

+0

Lo stesso qui. La domanda è molto legata alla programmazione. –

+1

Non ho mai avuto perdita di dati che posso attribuire alla rimozione di un dispositivo di archiviazione USB senza eseguire "rimuovere in modo sicuro l'hardware". Mi assicuro che le operazioni di copia dei file siano complete (la finestra di dialogo "copia i file" scompare). Sono estremamente fortunato? – Les

risposta

3

Ecco una funzione che ho usato per irrigare i dati su un'unità USB prima di espellere a livello di codice. Funzionalità di cloni da Mark Russinovich's "Sync" utility. Non ho avuto problemi con questo codice ed è stato eseguito su molti sistemi per un paio di anni.

La parte più rilevante di questo codice è la chiamata a FlushFileBuffers.

function FlushToDisk(sDriveLetter: string): boolean; 
var 
    hDrive: THandle; 
    S:  string; 
    OSFlushed: boolean; 
    bResult: boolean; 
begin 
    bResult := False; 
    S := '\\.\' + sDriveLetter + ':'; 

    //NOTE: this may only work for the SYSTEM user 
    hDrive := CreateFile(PAnsiChar(S), GENERIC_READ or 
    GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, 
    OPEN_EXISTING, 0, 0); 
    OSFlushed := FlushFileBuffers(hDrive); 

    CloseHandle(hDrive); 

    if OSFlushed then 
    begin 
    bResult := True; 
    end; 

    Result := bResult; 
end; 
+2

Questo serve per scaricare tutti i file aperti sul volume. Se Max si preoccupa solo dei file che sta scrivendo il suo programma, e non di altri file che l'utente potrebbe scrivere sull'unità con altri mezzi, probabilmente può semplicemente svuotare i manici sui suoi file invece di svuotare l'intero volume, e quindi non avrebbe bisogno di privilegi amministrativi. –

+0

È quasi impossibile garantire che non ci sarà alcuna corruzione. Il flash disk può essere estratto in qualsiasi momento. Penso che la risposta di MSalters sia più corretta. Sono d'accordo con Rob, è largo su disco. – Matt

+0

Perché questo codice usa 3 vars (OSFlushed, bResult e Result) quando solo uno sembra fare il lavoro? – EMBarbosa

2

qualunque cosa accada, è possibile scollegare il dispositivo da soli, voglio dire programmaticamente. allora sarai completamente sicuro di aver rimosso il dispositivo correttamente.

dare un'occhiata alle risposte per questa domanda: safe-remove-usb-drive-using-win32-api. specialmente this link to a msdn kb article dato nella risposta.

+1

Ma cosa succede se l'utente non vuole rimuovere l'unità USB? – simon

+0

l'utente sta già rimuovendo l'unità USB, non credo che ne abbia più bisogno. più seriamente, se stava aspettando più a lungo di usare l'unità, il file sarebbe finito scritto su disco (il file non è conservato per sempre nella cache). (sto trattando ogni giorno con questo tipo di clienti, più semplice è per loro, meglio è per tutti, dite loro che non possono usare l'unità, è semplice, dite loro che devono andare a "rimuovere in modo sicuro l'hardware", È troppo, posso scommettere che il nostro OP ha già del codice per rilevare automaticamente l'inserimento del drive USB e copiare il file necessario su un percorso predeterminato) –

+1

Adrien, sappiamo solo che l'utente sta rimuovendo l'unità * a volte *. Non sappiamo che l'utente * rimuove sempre l'unità dopo averla salvata. Inoltre, non sappiamo se l'unità viene utilizzata per cose diverse da questo programma. –

11

Quando si apre il file, specificare "write through" (FILE_FLAG_WRITE_THROUGH flag su CreateFile()). Questo costringerà il sistema operativo a scrivere direttamente il file. Potrebbe essere ancora nella cache del sistema operativo per accelerare le letture successive, ma non è un problema per te.

Se si vuole svuotare i buffer di file, c'è naturalmente sempre FlushFileBuffers()

+0

Quando utilizzo FlushFileBuffers(), posso essere sicuro che il file sia archiviato fisicamente sull'unità USB? Quindi, non svanisce, dopo che "incontrollato" si scollega? –

+1

@max: Sì, a patto che ci sia abbastanza tempo tra la chiamata a FlushFileBuffers() e la rimozione per l'esecuzione della scrittura fisica. IOW, se provi a scrivere un file da 2 GB sul disco USB, chiama FlushFileBuffers(), quindi + immediatamente + rimuovi l'unità, non può ancora essere completamente scritto - non c'è abbastanza tempo per completare l'operazione di scrittura effettiva. Devi istruire i tuoi utenti su come rimuovere in sicurezza l'unità, o almeno attendere fino a quando l'app non gli dice che possono rimuoverlo; la tua app può capire quanto tempo deve aspettare prima di dare loro quel OK. –

+3

Ken, lo fai sembrare che FlushFileBuffers ritorni prima che abbia finito di svuotare i buffer dei file. È corretto? Se sì, allora * come * dovrebbe il programma capire quanto tempo deve aspettare? –

Problemi correlati