Skip to main content

atomic_write

Function atomic_write 

Source
pub fn atomic_write(path: &Path, contents: &[u8]) -> Result<()>
Expand description

Writes contents to path so that a crash or a power cut leaves either the file that was there before or the new one, never half of either.

The parent directory has to exist; it is not created. The temporary file is written in that same directory, because a rename cannot cross a file system. On Unix systems the new file keeps the permissions of the file it replaces, so a private file stays private.

A path that is a symbolic link is written through: the file it points at is replaced and the link stays a link, so a settings file linked from a dotfiles repository keeps being that repository’s file. The temporary file is then written next to the file the link points at, and the new file keeps that file’s permissions. A link to a file that does not exist yet creates that file. Links pointing at links are followed to the end.

On Unix systems the directory is flushed after the rename, which is what makes the new name survive a power cut. On other platforms, Windows among them, the standard library cannot open a directory to flush it, so that step is skipped: the file’s own contents are still flushed before the rename, so no half-written file appears, but a power cut in the moment after the rename can leave the old file. Doing better needs calls the framework cannot make without unsafe, which it forbids.

§Errors

Returns the I/O error of the first step that failed. The temporary file is removed when a step after it fails, so a failed write leaves nothing behind. Links that point at each other in a loop are an error, and nothing is written.