1

I've written code that saves progress in my game, but one of my biggest fears is the brief window of time during saving when that data might become corrupted should the computer crash or lose power.

Is there standard methodology using only C's standard I/O header, to ensure the previous save/file will be safe should the program crash while overwriting it, that doesn't leave behind temporary files?

chux - Reinstate Monica
  • 113,725
  • 11
  • 107
  • 213
Anne Quinn
  • 10,856
  • 7
  • 40
  • 83
  • 2
    You could save the progress into a temporary file, and then when the save is completed, you could delete the original and rename the temporary. – PC Luddite Oct 23 '15 at 02:24
  • 4
    You don't need to delete the original first, just rename the temporary. Or rename the original to a backup, and then rename the new file. That is the traditional way to do it in Unix, eliminating the chance of data loss caused by a crash between deletion and renaming. I don't know how easy it is do that in other systems, such as Windows. – Thomas Padron-McCarthy Oct 23 '15 at 02:42
  • 2
    A crash between deletion and renaming would not matter. The app would check for the presence of both original and temp filenames on startup and take the appropriate action/s. – Martin James Oct 23 '15 at 02:45
  • 1
    @ThomasPadron-McCarthy I think that's pretty standard procedure across platforms. It's equally as simple to do through the WinAPI. – PC Luddite Oct 23 '15 at 02:52

2 Answers2

1

Algorithm

Code writes progress(t), t and a verification code (check sum, CRC, etc.) in 1 file.
Next time, code writes progress(t+1), t+1 and with its verification code in another file.
Repeat the above two.

To restore, read both files and certainly at least 1 will have a valid: progress, some t and a verification code. If both are good, use the later one (greater t).

chux - Reinstate Monica
  • 113,725
  • 11
  • 107
  • 213
1

A similar idea incorporating post's comments:
@PC Luddite @Thomas Padron-McCarthy @Martin James

The central issue is that either A) a gap in time exist between having a valid "state" file or B) a small interval exists with 2 valid files. So a worst case failure ends with 0 files using A and 2 files using B. Clearly B is preferable.

Writing the state Assume code could crash just before, during, or just after any step except #1.

  1. Assume initial state (or progress) file exist: State.txt.
  2. If exist, delete earlier temp file(s). (House-keeping)
  3. Write new state in temporary file: State_tmp1.txt. To know this completed, some check code should be part of the "state". This step could be combined with the previous step as an over-write.
  4. Pedantic step - optional. Rename State_tmp1.txt to State_tmp2.txt to verify some aspects of code having rename privileges.
  5. Rename State.txt to State_tmp3.txt. This is the critical step. Up to now, any failure is inconsequential as State.txt exist. Until the next step is complete, no State.txt may exist, yet at least 1 tmp file exist.
  6. Rename State_tmp1.txt to State.txt. (or from State_tmp2.txt if step 4 used.)
  7. Delete tmp files.

Reading the state.

  1. Search for State.txt, if found and valid (Passes validity check), proceed to step 3.
  2. Else, seek for tmp files and use latest valid one. (More work to restore state not yet detailed.
  3. Clean-up - delete tmp files.
Community
  • 1
  • 1
chux - Reinstate Monica
  • 113,725
  • 11
  • 107
  • 213