285bf66b61 | ||
---|---|---|
LICENSE | ||
README.md | ||
go.mod | ||
go.sum | ||
unit_test.go | ||
writefile.go |
README.md
src.lwithers.me.uk/go/writefile
This package implements the common Unix technique of writing a new file by first writing a temporary file, then ensuring it is fsync()ed, before calling rename() to atomically move into its final resting place.
What problem does this solve? It prevents writing a partial output file, or corrupting an existing file with a partially-written new version, if there is a crash or other unexpected exit of the program.
Example:
finalFname, out, err := writefile.New("my-file")
if err != nil {
return err
}
defer writefile.Abort(out)
// … write to ‘out’ …
return writefile.Commit(finalFname, out)
The New()
method returns a final filename string which is later passed to
Commit()
. This will typically match the filename argument passed to New()
,
except if the file is a symlink, in which case the symlink is dereferenced
and its target is overwritten. If this behaviour is undesired, the following
pattern may be used instead:
out, err := writefile.NewNoDeref("my-file")
// …
return writefile.Commit("my-file", out)
The temporary file being written will have 0600 permissions. If an existing
file is overwritten by Commit()
, the call will attempt to inherit the existing
permissions. Otherwise, the final file is left with 0600.