问题
I have an application that stores data in XML file every 500 ms using XElement object's .Save("path") method. The problem is : when a sudden shutdown is occurred the content of the file is deleted so on the next run of the application the file can not be used.
How to prevent that / make sure the data will not be lost? P.S: I'm using .NET 2010 C# under windows 7
I've made an experiment: instead of writing to the same data.xml file I've created (by copying from the original file) a new file each time and when the power was off while copying from data.xml file it would corrupt all previously created files?!?!?
回答1:
Let's assume your file is data.xml
. Instead of writing to data.xml
all the time, write to a temporary file data.xml.tmp
, and when finished, rename it to data.xml
. But renaming will not work if you already have a data.xml
file, so you will need to delete it first and then rename the temporary file.
That way, data.xml
will contain the last safe data. If you have a sudden shutdown, the incomplete file will be the temporary data.xml.tmp
. If your program tries to read the file later on and there is no data.xml
file, that means the shutdown happened between the delete and rename operations, so you will have to read the temporary file instead. We know it is safe because otherwise there would be a data.xml
file.
回答2:
You can use a 2-phase commit:
- Write the new XML to a file with a different name
- Delete the old file
- Rename to new file to the old name
This way, there will always be at least one complete file.
If you restart, and the standard name doesn't exist, check for the different name.
回答3:
This one could be a life savior but with little more efforts. There should be a separate process which does
- Take backup to its stash automatically whenever the file gets updated.
- It internally maintains two versions in a linked list.
- If the file gets updated, then the latest shall be updated to
HEAD using linkedList.AddFirst()
and the least version pointed byTAIL
could be removed bylinkedList.RemoveLast()
. - And of course, it should scan and load the stash about the latest version available in the stash during startup.
In the hard shutdown scenario, when the system starts up next time, this process should check whether the file is valid / corrupted. If corrupted, then restore the latest from HEAD
and subscribe for FileChanged
notification using a simple FileSystemWatcher
.
This approach is well tested.
Problems seen
- What if the Hard shutdown happens while updating the
HEAD
? -- Well, there is another version we have it in the stash next toHEAD
- What if the Hard shutdown happens while updating the
HEAD
when the stash is empty? -- We know that the file was valid while updatingHEAD
. The process shall try copying again at next startup since it is not corrupted. - What if the stash is empty and the file has been corrupted? -- This is the death pit and no solution is available for this. But this scenario occurs only when you deploy this recovery process after the file corruption happened.
来源:https://stackoverflow.com/questions/16156203/xml-file-data-is-lost-when-sudden-shutdown-is-occurred