Go

Atomic File Write (temp + rename)

admin by @admin ADMIN
1d ago
May 31, 2026
Public
0 0 up · 0 down Sign in to vote
Write to a temp file in the SAME directory, then `os.Rename` to the final name. Rename is atomic on POSIX — readers never see a half-written file.
Go
Raw
package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func atomicWrite(path string, data []byte, perm os.FileMode) error {
    dir := filepath.Dir(path)
    tmp, err := os.CreateTemp(dir, "."+filepath.Base(path)+".*.tmp")
    if err != nil { return err }
    tmpName := tmp.Name()

    defer func() {
        // Best-effort cleanup if rename never happened
        if _, err := os.Stat(tmpName); err == nil { os.Remove(tmpName) }
    }()

    if _, err := tmp.Write(data); err != nil { tmp.Close(); return err }
    if err := tmp.Sync();             err != nil { tmp.Close(); return err }
    if err := tmp.Close();            err != nil { return err }
    if err := os.Chmod(tmpName, perm); err != nil { return err }
    return os.Rename(tmpName, path)
}

func main() {
    err := atomicWrite("/var/lib/myapp/state.json",
        []byte(`{"ok": true}`), 0644)
    fmt.Println(err)
}
Tags

Save your own code snippets

Create a free account and build your private vault. Share publicly whenever you want.