writefile/README.md

1.4 KiB
Raw Permalink Blame History

src.lwithers.me.uk/go/writefile

GoDoc

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.