Kiedy zapisuję plik na urządzeniu USB w mojej aplikacji delphi, w jaki sposób mogę się upewnić, że plik jest rzeczywiście (na stałe) zapisany na USB, gdy "Bezpiecznie usuń sprzęt" nie jest wykonywany (w szczególności zapomniany w użyciu)?
Nie można polecić klientowi korzystania z funkcji Windows "Bezpieczne usuwanie sprzętu".
Czy istnieje polecenie interfejsu systemu Windows do opróżnienia bufora, aby wszystkie dane były zapisywane na dysku USB na stałe?Jak upewnić się, że plik został na stałe zapisany na USB, gdy użytkownik nie używa "Bezpiecznie usuń sprzęt"?
Odpowiedz
Oto funkcja Kiedyś przepłukać dane na dysku USB przed wyjęciem go programowo. Ta funkcja klonów od Mark Russinovich's "Sync" utility. Nie miałem żadnych problemów z tym kodem i od kilku lat działa na wielu systemach.
Najważniejszą częścią tego kodu jest połączenie z numerem 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;
To jest do opróżniania wszystkich otwartych plików na woluminie. Jeśli Max jest zaniepokojony tylko plikami, które pisze jego program, a nie innymi plikami, które użytkownik zapisuje na dysku innymi metodami, prawdopodobnie będzie mógł po prostu przepłukać uchwyty do swoich plików zamiast spłukiwać cały wolumin i w związku z tym nie potrzebowałby przywilejów administracyjnych. –
Niemożliwe jest zagwarantowanie, że nie będzie jakiegoś uszkodzenia. Dysk flash można wyciągnąć w dowolnym momencie. Myślę, że MSALTER odpowiada, jest bardziej poprawny. Zgadzam się z Robem, to jest dysk szeroki. – Matt
Dlaczego ten kod używa 3 vars (OSFlushed, bResult i Result), gdy tylko jeden wydaje się wykonywać zadanie? – EMBarbosa
cokolwiek się stanie, możesz odłączyć urządzenie samodzielnie, mam na myśli program. wtedy będziesz całkowicie pewien, że poprawnie usunęli urządzenie.
spójrz na odpowiedzi na to pytanie: safe-remove-usb-drive-using-win32-api. zwłaszcza this link to a msdn kb article podany w odpowiedzi.
Ale co, jeśli użytkownik nie chce usunąć dysku USB? – simon
użytkownik usuwa już napęd USB, nie sądzę, że już go potrzebuje. bardziej poważnie, gdyby czekał dłużej na użycie napędu, plik zostanie zapisany na dysk (plik nie będzie trwał na stałe w pamięci podręcznej na zawsze). (Codziennie mam do czynienia z tego rodzaju klientem, im prostsze dla nich, tym lepiej dla wszystkich, powiedz im, że nie mogą korzystać z napędu, to proste, powiedz im, że muszą iść "bezpiecznie usunąć sprzęt", To jest zbyt dużo, mogę założyć się, że nasz OP ma już jakiś kod do automatycznego wykrywania wstawiania napędu USB i kopiowania potrzebnego pliku do z góry określonej ścieżki) –
Adrien, wiemy tylko, że użytkownik usuwa dysk * czasami *. Nie wiemy, że użytkownik * zawsze * usuwa dysk po zapisaniu. Nie wiemy również, czy dysk jest używany do innych celów niż ten program. –
Po otwarciu pliku określ "zapisz przez" (FILE_FLAG_WRITE_THROUGH flaga na CreateFile()). To zmusi system operacyjny do bezpośredniego zapisu pliku. Być może nadal znajduje się w pamięci podręcznej systemu operacyjnego, aby przyspieszyć kolejne odczyty, ale nie stanowi to dla ciebie problemu.
Jeśli chcesz opróżnić bufory plików, jest oczywiście zawsze FlushFileBuffers()
Kiedy używam FlushFileBuffers(), czy mogę mieć pewność, że plik jest przechowywany fizycznie na dysku USB? Więc nie znika po "niekontrolowanym" odłączeniu? –
@max: Tak, o ile jest wystarczająco dużo czasu między wywołaniem FlushFileBuffers() i usunięciem, aby wystąpił fizyczny zapis. IOW, jeśli spróbujesz zapisać plik 2GB na dysku USB, wywołaj FlushFileBuffers(), a następnie + natychmiastowo + wyjmij napęd, nadal nie można go całkowicie napisać - po prostu nie ma wystarczająco dużo czasu na ukończenie faktycznej operacji zapisu. Musisz uświadomić użytkownikom, jak bezpiecznie usunąć dysk, lub przynajmniej poczekać, aż aplikacja poinformuje ich, że mogą go usunąć; Twoja aplikacja może dowiedzieć się, ile czasu musi upłynąć, zanim je wyda. –
Ken, sprawiłeś, że brzmi jak FlushFileBuffers powróci, zanim faktycznie skończy opróżnianie buforów plików. Czy to jest poprawne? Jeśli tak, to * jak * program powinien określić, ile czasu musi czekać? –
Do tego, kto głosował, by zamknąć jako "Nie związane z programowaniem", proszę ponownie przeczytać pytanie. –
To samo tutaj. Pytanie jest bardzo związane z programowaniem. –
Nigdy nie miałem utraty danych, które mogę przypisać usunięciu urządzenia pamięci USB bez wykonywania "bezpiecznego usuwania sprzętu". Upewniam się, że operatory kopiowania plików są kompletne (okno dialogowe "kopiuj pliki" znika). Czy jestem niezmiernie szczęśliwy? – Les