tags:

views:

122

answers:

3

For a file on disk, is the Win32 function FlushFileBuffers as reliable and certain as closing the file using CloseHandle then re-opening the file using CreateFile?

Are there circumstances where CloseHandle then CreateFile are better because they save the data correctly to disk when FlushFileBuffers does not?

+2  A: 

According to the documentation, FlushFileBuffers does write everything to the disk. However, it probably doesn't hurt to test it yourself. I've done BRS testing (big red switch ... well PCs used to have big red switches) in the past, and I found that it did cause everything to be written. After the call to FlushFileBuffers, turn the PC off without a clean shutdown. Turn it back on and see if the data is all there. The behavior may change by OS (in theory it shouldn't ... but you never know). It was quite some time ago that I did tests like that (it was on XP or possibly even Windows 2000).

And I suppose it goes without saying, but you probably don't want to do this testing on a workstation that you really care about.

Mark Wilkins
+4  A: 

It is better, CloseHandle() doesn't flush the file system cache write buffers. Beware of the cost, it can take a long time to get the data to the disk. The FILE_FLAG_NO_BUFFERING option for CreateFile allows you to avoid flushing. But it is very expensive and difficult to get right due to the limitations on the written data.

Hans Passant
I am getting 120 FlushFileBuffer calls per second on an ordinary PC and hard drive. I can CloseHandle and CreateFile at 75,000 per second if it is OPEN_EXISTING, and at 33,000 for CREATE_ALWAYS FILE_ATTRIBUTE_NORMAL. It drops to 5,000 for CREATE_ALWAYS (FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH).
soid
From this thread http://www.mail-archive.com/[email protected]/msg10325.html the reason I get 120 per second is that the "disk drive is spinning at 7200 RPM, and each FlushFileBuffers call requires one revolution of the disk, that means you can have at most 120 FlushFileBuffer operations ... per second." Note that the file meta-data is updated by FlushFileBuffers so my calls were writing data to disk every time even though I was not writing data into the file - I had a contant filesize of zero.
soid
+1  A: 

Although this information is not related to Delphi, but the most deployed SQL-database on earth, sqlite (used for example in Firefox) takes care on such things and you can read a lot ot atomic operations here: http://www.sqlite.org/atomiccommit.html Below is a quote from the article about FlushFileBuffers

9.2 Incomplete Disk Flushes

SQLite uses the fsync() system call on Unix and the FlushFileBuffers() system call on w32 in order to sync the file system buffers onto disk oxide as shown in step 3.7 and step 3.10. Unfortunately, we have received reports that neither of these interfaces works as advertised on many systems. We hear that FlushFileBuffers() can be completely disabled using registry settings on some Windows versions. ...

informin
Thank you. I tagged it Delphi because I am doing a little debugging of an open source database written in Delphi called FlashFiler and the discussion might have descended into the code. It is more general than just Dephi.
soid