views:

21

answers:

2

Hi,

I'm using File.createTempFile to create regular files I want to keep, the reason I use this method is because it guarantees a unique file name. However I'm seeing a strange thing with files created by this method: After I flush and closed the output stream on this file, I crash the machine running JVM deliberately, I assumed since the stream is flushed and closed, the file should contain valid data. However, sometimes the file gets filled with 0x0 instead (Note I'm testing this on a VMWare box running WinXP and latest Sun JVM 1.6).

Is the problem caused by the temp file or is this some kind of general problem which applies to all Java file io? What should I do to ensure the data gets flushed to harddrive?

Thanks

A: 

Most modern filesystem access is subject to this sort of problem - see about filesystem journaling for a quick introduction to the problem.

The short of it is - if your system crashes, recently updated files may revert to previous data. If you recently created the file, it may be zero-filled.

On UNIX you prevent this using fsync and/or fdatasync. I'm not a Windows guy but this might be a starting point: cross platform fsync(). I'm not sure how to do it from Java.

Steven Schlansker
His claim is that he closed file properly before crashing VM. I suspect there is something wrong with the I/O code that writes to this file.
Alexander Pogrebnyak
A few other SO questions indicate that closing is not sufficient. Here's one... http://stackoverflow.com/questions/730521/really-force-file-sync-flush-in-java
Steven Schlansker
A: 

In addition to flush(), try calling output.getFileDescriptor().sync() on your FileOutputStream.

erickson
This seems to be the ideal method, unfortunately, it doesn't work. If I wait a while longer before the crash, I can see the log (the log file suffers the same problem as the data file, so if I crash immediately the log is lost too, no way to know what happened), and it shows sync method fails with SyncFailedException every time I called it (tried 5 times in a for loop). So I suspect the underlying OS doesn't support this. (Note: when I can see the log, even if sync failed, the data still get written successfully, but it still fails if I crash the machine very soon after stream closure (1-2s).
su27k
Sorry, I made a mistake in my test code, sync() is the correct method to use, thanks!
su27k