terborac
terborac

Reputation: 363

Best practice for writing big files

I need to write a big file in my project.


What I learned:


My code snippet:

[NotNull]
public static async Task WriteAllTextAsync([NotNull] string path, [NotNull] string content) 
{
    string temporaryFilePath = null;
    try {
        temporaryFilePath = Path.GetTempFileName();
        using (var stream = new StreamWriter(temporaryFilePath, true)) {
            await stream.WriteAsync(content).ConfigureAwait(false);
        }            

        File.Delete(path);
        File.Move(temporaryFilePath, path);
    }
    finally {
        if (temporaryFilePath != null) File.Delete(temporaryFilePath);
    }
}

My Question:

Upvotes: 3

Views: 1165

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1499790

The file will be missing if the app crashes between File.Delete and File.Move. Can I avoid this?

Not that I'm aware of, but you can detect it - and if you use a more predictable filename, you can recover from that. It helps if you tweak the process somewhat to use three file names: the target, a "new" file and an "old" file. The process becomes:

  • Write to "new" file (e.g. foo.txt.new)
  • Rename the target file to the "old" file (e.g. foo.txt.old)
  • Rename the "new" file to the target file
  • Delete the "old" file

You then have three files, each of which may be present or absent. That can help you to detect the situation when you come to read the new file:

  • No files: Nothing's written data yet
  • Just target: All is well
  • Target and new: App crashed while writing new file
  • Target and old: App failed to delete old file
  • New and old: App failed after the first rename, but before the second
  • All three, or just old, or just new: Something very odd is going on! User may have interfered

Note: I was unaware of File.Replace before, but I suspect it's effectively just a simpler and possibly more efficient way of doing the code you're already doing. (That's great - use it!) The recovery process would still be the same though.

Upvotes: 7

110mat110
110mat110

Reputation: 624

You can use File.Replace instead of deleting and moving files. In case of hard fault (electricity cut or something like this) you will always lost data, you have to count with that.

Upvotes: 6

Related Questions