John
John

Reputation: 1994

Cause of corrupted file contents

I'm having a recurring problem with an app in the wild.

It has a fairly simple XML file it dumps out every now and then, something like every 30 minutes.

The data files are often quite small - e.g. < 5KB.

It doesn't hold a lock on the file - it just recreates it from scratch each time.

I was lucky enough to see the problem occur on a test machine, and what I observed was that the file was corrupted and set to "nulls" (i.e. 00 in Hex). What's really weird is that it is exactly the correct length compared to what it should have been.

I've tried to be really careful in my saving process:

  1. I write the xml to a temp file in the same directory as I'm going to really save it
  2. I perform a Win32 MoveFile() with the MOVEFILE_WRITE_THROUGH set (so it should block until the move is really and truly complete), to move the file to replace the existing data file

I even lock on a Mutex to make sure this isn't a threading issue.

It doesn't happen that often, like maybe 1 in 1000 users.

Now I have in the past observed data files being corrupted by a power failure or BSOD during writing, and I've seen things like the 32kb of a file being all NULL.

But it just seems like it's happening more than I'd expect, given the chances of a power failure during the write, and espcecially since I'm using MOVEFILE_WRITE_THROUGH.

Any ideas?

John


Answers to some questions:

Upvotes: 8

Views: 4138

Answers (3)

Pashupati Khanal
Pashupati Khanal

Reputation: 743

I was facing same problem and my code is exactly as you explained, this seems quite unorthodox but to make it work making multiple backup file was a solution to me, while reading if some issue occurs I assume it is corrupted and I read it from that backup file.

Upvotes: -1

Calvin Wu
Calvin Wu

Reputation: 142

As my experience, it is possibly cause by file cache in windows. You should try to save file using CreateFile() with FILE_FLAG_WRITE_THROUGH pass in. Saving file by this way can make sure the file will land in hard disk.

I had wroten a little program to test this. If the program create file with std::ofstream and use MoveFileEx() with MOVEFILE_WRITE_THROUGH to move that file, the file corrupt almost every time if power off (not shutdown) the VM immediately after file move finished; Otherwise, if the program use CreateFile() with FILE_FLAG_WRITE_THROUGH to create file and do the same thing again, The file didn't corrupt (I tested for about 10 times but it didn't happened).

After those simple tests, I think you should try to use CreateFile() with FILE_FLAG_WRITE_THROUGH to solve your problem.

More information:
File Caching (Windows)
Windows Internals, 6th edition, Chapter 11 Cache Manager

Upvotes: 4

Thomas Matthews
Thomas Matthews

Reputation: 57729

Here are some ideas:

  • Flush the stream after critical information or before long periods of no writing.
  • Verify that no other entities are writing to the file.
  • Verify that the buffered data is not overwritten by other code.
  • Close the file between long durations of no writing.

Upvotes: 0

Related Questions