Skip to content

AtomicFile

Namespace Nfty.Core.Formats in assembly Nfty.Core.

public static class AtomicFile

Replaces a file as one step: the new contents are written to a temp file beside it, then moved over the original, so a failure or a crash leaves either the old file or the new one, never half of one.

The temp name is unique per write. It used to be the fixed path + ".tmp" in several places, which two problems shared. The cleanup deletes the temp file on failure, so a writer that lost a race to the same path deleted the file the winner was still filling — a no-op on Windows, where the winner's handle blocks the delete, and a success on POSIX, where it would strand the winner's move. And ZipArchiveMode.Create opens FileMode.CreateNew, so a temp file left behind by a crashed write made every later save fail with "the file already exists" until someone deleted it by hand.

A per-write suffix makes "a writer only ever deletes the file it created" true by construction rather than by timing. It does not serialize two writers to the same destination — nothing here can, and the caller that owns the edit is the one that must (see ExplorerViewModel.MoveLayerAsync's in-flight guard).

Methods

Replace(string, Action<string>)

public static void Replace(string path, Action<string> writeTemp);

Writes through a unique temp file beside path, then replaces it.

Parameters

  • path (string) - The file to replace; created when absent.
  • writeTemp (Action<string>) - Writes the new contents to the path it is given, which does not exist yet.

Exceptions

  • ArgumentException - path is null or whitespace.
  • ArgumentNullException - writeTemp is null.

ReplaceAsync(string, Func<string, Task>)

public static Task ReplaceAsync(string path, Func<string, Task> writeTemp);

The awaiting twin of AtomicFile.Replace().

Parameters

  • path (string) - The file to replace; created when absent.
  • writeTemp (Func<string, Task>) - Writes the new contents to the path it is given, which does not exist yet.

Returns. A task that completes when the file has been replaced.

Exceptions

  • ArgumentException - path is null or whitespace.
  • ArgumentNullException - writeTemp is null.