AtomicFile¶
Namespace Nfty.Core.Formats in assembly Nfty.Core.
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>)¶
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-pathis null or whitespace.ArgumentNullException-writeTempis null.
ReplaceAsync(string, Func<string, Task>)¶
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-pathis null or whitespace.ArgumentNullException-writeTempis null.