2009-10-28 2 views
11

Когда я сохраняю файл на USB-устройстве в своем приложении delphi, как я могу убедиться, что файл действительно (постоянно) сохранен на USB-устройстве, когда «Безопасное удаление оборудования» не выполняется (особенно забыто использовать)?
Говорить, что наш клиент использует функцию «Безопасное извлечение оборудования», не работает.
Есть ли команда API окон для сброса буфера, чтобы все данные записывались на USB-накопитель постоянно?Как убедиться, что файл был сохранен на USB-накопителе, когда пользователь не использует «Безопасное удаление оборудования»?

+7

Кому-то, кто проголосовал за закрытие как «Не связанное с программированием», пожалуйста, перечитайте вопрос. –

+0

То же самое здесь. Вопрос очень связан с программированием. – 2009-10-28 08:57:05

+1

У меня никогда не было потери данных, которую я могу приписать удалению USB-накопителя без «безопасного удаления оборудования». Я уверен, что операции копирования файлов завершены (диалог «файлы копий» уходит). Мне очень повезло? – Les

ответ

3

Вот функция, я использовал для очистки данных на диск USB перед извлечением его программно. Эта функциональность клонов от Mark Russinovich's "Sync" utility. У меня не было проблем с этим кодом, и он работает на многих системах уже пару лет.

Наиболее подходящей частью этого кода является вызов 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

Это для очистки всех открытых файлов на томе. Если Макс беспокоится только о файлах, которые пишет его программа, а не о любых других файлах, которые пользователь мог бы записать на диск с помощью других средств, то он, вероятно, может просто очистить дескрипторы от своих файлов, а не очищать весь том, и поэтому ему не нужны административные привилегии. –

+0

Почти невозможно гарантировать, что не будет никакой коррупции. Флэш-диск можно вытащить в любое время. Я думаю, что ответ MSalters вернее. Я согласен с Робом, это диск в ширину. – Matt

+0

Почему этот код использует 3 vars (OSFlushed, bResult и Result), когда только один, похоже, выполняет эту работу? – EMBarbosa

2

все, что угодно, вы можете отключить устройство самостоятельно, я имею в виду программно. то вы полностью убедитесь, что они правильно удалили устройство.

взгляните на ответы на этот вопрос: safe-remove-usb-drive-using-win32-api. особенно this link to a msdn kb article, указанным в ответе.

+1

Но что, если пользователь не хочет удалять USB-накопитель? – simon

+0

Пользователь уже удален USB-накопитель. Мне больше не нужно больше это нужно. более серьезно, если он дольше будет ждать использования диска, файл будет записан на диск (этот файл не будет храниться в кэше навсегда). (я каждый день занимаюсь этим видом клиента, тем проще для них, тем лучше для всех. Скажите им, что они не могут использовать диск, это просто, скажите им, что они должны пойти «безопасно удалить оборудование», это слишком много. Я могу поспорить, что у нашего OP уже есть некоторый код для автоматического обнаружения вставки USB-диска и копирования необходимого файла на заданный путь) –

+1

Adrien, мы знаем только, что пользователь удаляет диск * иногда *. Мы не знаем, что пользователь * всегда * удаляет накопитель после сохранения. Мы также не знаем, используется ли диск для других целей, кроме этой программы. –

11

Когда вы открываете файл, укажите «write through» (флаг FILE_FLAG_WRITE_THROUGH для CreateFile()). Это заставит ОС напрямую записать файл. В кэше ОС все еще может ускорить последующие чтения, но это не проблема для вас.

Если вы хотите, чтобы очистить буферы файлов, есть, конечно, всегда FlushFileBuffers()

+0

Когда я использую FlushFileBuffers(), могу ли я быть уверенным, что файл физически хранится на USB-накопителе? Значит, он не исчезает после «неконтролируемого» отключения? –

+1

@max: Да, пока есть достаточно времени между вызовом FlushFileBuffers() и удалением для физической записи. IOW, если вы попытаетесь записать файл 2 ГБ на USB-диск, вызовите FlushFileBuffers(), а затем + мгновенно + удалите диск, он все равно может быть полностью не написан - достаточно времени, чтобы завершить фактическую операцию записи. Вы должны обучить своих пользователей тому, как безопасно удалить диск, или, по крайней мере, подождать, пока ваше приложение не сообщит им, что они могут удалить его; ваше приложение может выяснить, сколько времени ему нужно подождать, прежде чем дать им это ОК. –

+3

Кен, вы заставляете его звучать так, как FlushFileBuffers вернутся, прежде чем он закончит промывку файловых буферов. Это верно? Если да, то * как * должна программа выяснить, как долго она должна ждать? –

Смежные вопросы