When I save a file on a USB within my delphi application, how can I make sure the file is really (permanently) saved on the USB, when "Safely Remove Hardware" is not performed (especially forgotten to use)?
Telling our customer to use the windows feature "Safely Remove Hardware" doesn't work.
Is there a windows API command to flush the buffer, so that all data are written to the USB drive permanently?
-
8To whoever voted to close as "Not programming related", please re-read the question. – Lasse V. Karlsen Oct 28 '09 at 08:56
-
The same here. The question is very much programming related. – Oct 28 '09 at 08:57
-
1I've never had data loss that I can attribute to removing a USB storage device without performing "safely remove hardware". I do make sure that file copy operatons are complete (the 'copy files' dialog goes away). Am I exceedingly lucky? – Les Oct 28 '09 at 13:05
-
Les: Yes. I have lost data plenty of times... – Jörgen Sigvardsson May 30 '11 at 10:54
3 Answers
When you open the file, specify "write through" (FILE_FLAG_WRITE_THROUGH flag to CreateFile()). This will force the OS to write out the file directly. It may still be in the OS cache to speed up subsequent reads, but that's not a problem for you.
If you do want to flush file buffers, there's of course always FlushFileBuffers()

- 173,980
- 10
- 155
- 350
-
When I use FlushFileBuffers(), can I be sure that the file is stored physically on the USB drive? So, it doesn't vanish, after "uncontrolled" unplug? – markus_ja Oct 28 '09 at 11:23
-
1@max: Yes, as long as there's enough time between the call to FlushFileBuffers() and the removal for the physical write to occur. IOW, if you try and write a 2GB file to the USB disk, call FlushFileBuffers(), and then +instantly+ remove the drive, it can still fail to be completely written - there's just not enough time allowed to complete the actual write operation. You need to educate your users on how to safely remove the drive, or at least wait until your app tells them they can remove it; your app can figure out how long it needs to wait before giving them that OK. – Ken White Oct 28 '09 at 12:41
-
3Ken, you make it sound like FlushFileBuffers will return before it has actually finished flushing the file buffers. Is that correct? If so, then *how* should the program figure out how long it needs to wait? – Rob Kennedy Oct 28 '09 at 13:43
Here's a function I used to flush data to a USB drive before ejecting it programmatically. This clones functionality from Mark Russinovich's "Sync" utility. I've had no problems with this code and it has been running on a lot of systems for a couple of years.
The most relevant part of this code is the call to 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;

- 13,248
- 9
- 69
- 119
-
2That's to flush all open files on the volume. If Max is only concerned about the files his program is writing, and not with any other files the user might be writing to the drive through other means, then he can probably just flush the handles to his files instead of flushing the whole volume, and he therefore wouldn't need administrative privileges. – Rob Kennedy Oct 28 '09 at 19:26
-
It's almost impossible to guarantee there won't be some corruption. The flash disk can be pulled out at any time. I think MSalters answer is more correct. I agree with Rob, it's disk wide. – hookenz Mar 01 '12 at 04:32
-
1Why this code use 3 vars (OSFlushed, bResult and Result) when just one seems to do the job? – EMBarbosa Jun 01 '12 at 16:59
-
1@EMBarbosa, good point. I added this mainly for clarity, not as an example of the most concise way to do it. – Mick Jun 01 '12 at 17:16
whatever happens, you can unplug the device yourself, i mean programatically. then you will be completely sure they have removed the device properly.
have a look at the answers for this question: safe-remove-usb-drive-using-win32-api. especially this link to a msdn kb article given in the answer.

- 1
- 1

- 22,486
- 6
- 42
- 73
-
1
-
the user is already removing the usb drive, i don't think he needs it anymore. more seriously, if he was waiting longer to use the drive, the file would end up written to disk (the file is not hold on cache forever). (i am dealing everyday with this kind of customer, the simpler it is for them, the better it is for everyone. tell them they can't use the drive, that's simple; tell them they must go to "safely remove hardware", that's too much. i can bet our OP already has some code to automatically detect USB drive insertion and copying the needed file to a predetermined path) – Adrien Plisson Oct 28 '09 at 10:22
-
1Adrien, we only know the user is removing the drive *sometimes*. We don't know that the user *always* removes the drive after saving. We also don't know whether the drive is being used for things other than this program. – Rob Kennedy Oct 28 '09 at 13:50
-
@rob: you are right, i was just making assumptions based on my own personal experience... my bad. – Adrien Plisson Oct 28 '09 at 14:32