API Reference
The API is split by intent: plain atomic writes (Write, WriteFunc) for the
common case, and *Verified variants (WriteVerified, WriteFuncVerified) when you
need TOCTOU protection against concurrent modification. WriteIfChanged is the
idempotent primitive for config writers and code generators.
Core Types
Section titled “Core Types”Fingerprint
Section titled “Fingerprint”An xxhash64 digest of file content at read time. A zero-value Fingerprint
indicates no prior file existed.
type Fingerprint [8]byteMethods
Section titled “Methods”// Returns true if the fingerprint represents no prior filefunc (fp Fingerprint) IsZero() bool
// Returns true if the given content produces the same fingerprintfunc (fp Fingerprint) Matches(content []byte) boolWrite functions
Section titled “Write functions”Writes data to path with crash durability (fsync + atomic rename). It does not
perform TOCTOU verification — use WriteVerified for that.
Use Write when concurrent modification is not a concern (temp files, first-time
creation, single-writer scenarios).
func Write(path string, data []byte) errorWriteVerified
Section titled “WriteVerified”Writes data to path with TOCTOU protection and crash durability. Data is staged
to a unique temp file, fsync’d, then verified against the fingerprint before atomic
rename.
The fingerprint must be computed via FingerprintFile before reading/modifying the
file. A zero-value fingerprint indicates the file should not yet exist; the write
fails with ErrConcurrentModification if another process creates it first. This
prevents the silent-skip footgun where a caller forgets to compute a fingerprint.
func WriteVerified(path string, data []byte, fingerprint Fingerprint) errorWriteIfChanged
Section titled “WriteIfChanged”Writes data to path only if it differs from the current on-disk content. Returns
changed=true if the file was written, false if the content was identical and the
write was skipped.
This is the idiomatic primitive for config-file writers and code generators that must not produce spurious diffs on re-runs: no content change means no file mutation, no mtime bump, no file-watcher trigger.
Race-safe for existing files: if another process modifies the file between the
fingerprint check and the atomic rename, returns ErrConcurrentModification. First-write
(file does not exist) uses a plain atomic write — there is no prior content to protect.
func WriteIfChanged(path string, data []byte) (changed bool, err error)Streaming write functions
Section titled “Streaming write functions”WriteFunc
Section titled “WriteFunc”Writes to path via a streaming callback with crash durability. The callback receives
a buffered writer (64KB buffer) and may stream content incrementally without holding the
full payload in memory. It does not perform TOCTOU verification — use
WriteFuncVerified for that.
Use WriteFunc instead of Write when the content is large or produced incrementally
(e.g. JSON encoders, diagram renderers).
func WriteFunc(path string, fn func(w io.Writer) error) errorWriteFuncVerified
Section titled “WriteFuncVerified”Writes to path via a streaming callback with TOCTOU protection and crash
durability. See WriteVerified for fingerprint semantics.
func WriteFuncVerified(path string, fn func(w io.Writer) error, fingerprint Fingerprint) errorFingerprinting helpers
Section titled “Fingerprinting helpers”FingerprintFromBytes
Section titled “FingerprintFromBytes”Computes an xxhash64 Fingerprint from raw content.
func FingerprintFromBytes(data []byte) FingerprintFingerprintFile
Section titled “FingerprintFile”Computes an xxhash64 Fingerprint from a file’s current content. Returns a zero-value
Fingerprint if the file does not exist.
func FingerprintFile(path string) (Fingerprint, error)Errors
Section titled “Errors”ErrConcurrentModification
Section titled “ErrConcurrentModification”Sentinel error indicating the file was modified by another process between the
fingerprint read and the write attempt. Always check with errors.Is.
var ErrConcurrentModification = errors.New("file was modified concurrently since read")Choosing the right function
Section titled “Choosing the right function”| If you… | Use |
|---|---|
| Just want a crash-durable write | Write |
| Must detect concurrent modification | WriteVerified |
| Write config/codegen output and skip no-op re-runs | WriteIfChanged |
| Stream large or incrementally-produced content | WriteFunc |
| Stream content AND need TOCTOU protection | WriteFuncVerified |
API Summary
Section titled “API Summary”| Symbol | Description |
|---|---|
Fingerprint |
[8]byte — xxhash64 digest of file content at read time |
Fingerprint.IsZero() |
Returns true for zero-value (no prior file) |
Fingerprint.Matches(data) |
Returns true if data produces the same fingerprint |
FingerprintFromBytes(data) |
Computes fingerprint from raw bytes |
FingerprintFile(path) |
Computes fingerprint from a file (zero if nonexistent) |
Write(path, data) |
Crash-durable atomic write (no TOCTOU check) |
WriteVerified(path, data, fp) |
Atomic write with TOCTOU fingerprint verification |
WriteIfChanged(path, data) |
Idempotent write — skips when content matches disk |
WriteFunc(path, fn) |
Streams content via callback (no TOCTOU check) |
WriteFuncVerified(path, fn, fp) |
Streams content via callback with TOCTOU verification |
ErrConcurrentModification |
Sentinel error: file changed between read and write |
Full API on pkg.go.dev
Section titled “Full API on pkg.go.dev”For the complete, always-up-to-date API documentation, see pkg.go.dev.