Skip to content
Free public beta until December 4, 2026: every course is open, no card needed. After that, the first chapter of each course stays free and full access is a one-time $39 ($19 for up to 100 founding members chosen for helpful feedback). Your progress is kept. How the beta works

Recipe

Replace a file atomically

Use when: a program rewrites a file that must never be seen half-written: settings, a summary, a saved game, a database's index

Goal: the file holds either its complete old contents or its complete new contents, whatever happens during the save

Taught in Errors and edge cases

  1. 1

    Build the temporary path next to the target, for example path.with_extension("tmp").

    Example

    For summary.txt, path.with_extension("tmp") gives summary.tmp, in the same folder. For data/summary.txt it gives data/summary.tmp.

    Why: rename only replaces in one step within one filesystem, and a folder is always on one filesystem.

  2. 2

    let mut f = File::create(&tmp)?; then f.write_all(bytes)? (or writeln! in a loop).

    Example

    The new summary has three lines: min 8.1, max 17.9 and mean 12.0. The program writes them to summary.tmp with writeln!. Say the power cuts after min 8.1. Then summary.tmp holds one line, and summary.txt still holds all three old lines, just as atomic.txt did in the program above.

    Why: all the risky work happens to a file nobody else is reading, so a crash here costs nothing.

  3. 3

    f.sync_all()?; then let f drop, closing the file.

    Example

    In the program above, write_lines ends with file.sync_all(). It runs only after every line was written, and the rename comes after it. So the rename never points the name at data that is still only in memory.

    Why: a completed write can still be in the operating system's memory; syncing makes sure the rename can't expose an empty file after a power cut.

  4. 4

    fs::rename(&tmp, &path)?;

    Example

    fs::rename(&tmp, &path)? renames summary.tmp to summary.txt. A reader who opens summary.txt just before gets the three old lines. One who opens it just after gets the three new lines. The name summary.tmp no longer exists.

    Why: the rename swaps which contents the name points to in one step, so readers see the old file or the new one, never a mix.

Common mistakes

  • Putting the temporary file in a system temp folder on another disk: the rename then fails with CrossesDevices.
  • Skipping sync_all: after a power cut the new name can point at a file whose data never reached the disk.
  • Using one fixed temporary name when two programs may save at once: they overwrite each other's temporary file. Use a unique name (section 6).