How to safely save data to an existing file with C#? <p>How do you safely save data to a file that already exists in C#? I have some data that is serialized to a file and I'm pretty sure is not a good idea to safe directly to the file because if anything goes wrong the file will get corrupted and the previous version will get lost.</p> <p>So this is what I've been doing so far:</p> <pre><code>string tempFile = Path.GetTempFileName(); using (Stream tempFileStream = File.Open(tempFile, FileMode.Truncate)) { SafeXmlSerializer xmlFormatter = new SafeXmlSerializer(typeof(Project)); xmlFormatter.Serialize(tempFileStream, Project); } if (File.Exists(fileName)) File.Delete(fileName); File.Move(tempFile, fileName); if (File.Exists(tempFile)) File.Delete(tempFile); </code></pre> <p>The problem is that when I tried to save to a file that was in my <a href="http://www.dropbox.com">Dropbox</a>, sometimes I got an exception telling me that it cannot save to a file that already exists. Apparently the first <code>File.Delete(fileName);</code> didn't delete the file right away but after a little bit. So I got an exception in the <code>File.Move(tempFile, fileName);</code> because the file existed and then the file got erased and my file got lost. </p> <p>I've used other applications with files in my Dropbox and somehow they manage to not mess it up. When I'm trying to save to a file in my Dropbox folder, sometimes I get a message telling me that the file is being used or stuff like that but I never had a problem with a file being erased.</p> <p>So what would it be the standard / best practice here?</p> <p>OK this is what I came up with after reading all answers:</p> <pre><code>private string GetTempFileName(string dir) { string name = null; int attempts = 0; do { name = "temp_" + Player.Math.RandomDigits(10) + ".hsp"; attempts++; if (attempts &gt; 10) throw new Exception("Could not create temporary file."); } while (File.Exists(Path.Combine(dir, name))); return name; } private void SaveProject(string fileName) { bool originalRenamed = false; string tempNewFile = null; string oldFileTempName = null; try { tempNewFile = GetTempFileName(Path.GetDirectoryName(fileName)); using (Stream tempNewFileStream = File.Open(tempNewFile, FileMode.CreateNew)) { SafeXmlSerializer xmlFormatter = new SafeXmlSerializer(typeof(Project)); xmlFormatter.Serialize(tempNewFileStream, Project); } if (File.Exists(fileName)) { oldFileTempName = GetTempFileName(Path.GetDirectoryName(fileName)); File.Move(fileName, oldFileTempName); originalRenamed = true; } File.Move(tempNewFile, fileName); originalRenamed = false; CurrentProjectPath = fileName; } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { if(tempNewFile != null) File.Delete(tempNewFile); if (originalRenamed) MessageBox.Show("'" + fileName + "'" + " have been corrupted or deleted in this operation.\n" + "A backup copy have been created at '" + oldFileTempName + "'"); else if (oldFileTempName != null) File.Delete(oldFileTempName); } } </code></pre> <p><code>Player.Math.RandomDigits</code> is just a little function I made that creates an string with n random digits.</p> <p>I don't see how could this mess up the original file unless the OS is going wacko. It's pretty close to Hans's answer except that I first save the file to a temporary file so that, if something goes wrong when serializing, I don't need to rename the file back to it's original name, which can also go wrong. Please! let me know if you find any flaw.</p>