Documentation ¶
Overview ¶
Package atomicfile implements all-or-nothing file replacement by staging output to a temporary file adjacent to the target, and renaming over the target when the temporary is closed.
If (and only if) the implementation of rename is atomic the replacement is also atomic. Since IEEE Std 1003.1 requires rename to be atomic, this is ordinarily true on POSIX-compatible filesystems.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Tx ¶ added in v0.3.0
Tx calls f with a File constructed by New. If f reports an error or panics, the file is automatically cancelled and Tx returns the error from f. Otherwise, Tx returns the error from calling File.Close.
func WriteAll ¶
WriteAll copies all the data from r to the specified target path via a File. It reports the total number of bytes copied.
Example ¶
package main import ( "fmt" "io" "log" "os" "path/filepath" "strings" "github.com/creachadair/atomicfile" ) var tempDir string func cat(path string) { f, err := os.Open(path) if err != nil { log.Fatalf("Open: %v", err) } defer f.Close() io.Copy(os.Stdout, f) } func main() { path := filepath.Join(tempDir, "writeall.txt") nw, err := atomicfile.WriteAll(path, strings.NewReader("I knew you were trouble"), 0640) if err != nil { log.Fatalf("WriteAll: %v", err) } fmt.Println(nw) cat(path) }
Output: 23 I knew you were trouble
func WriteData ¶
WriteData copies data to the specified target path via a File.
Example ¶
package main import ( "io" "log" "os" "path/filepath" "github.com/creachadair/atomicfile" ) var tempDir string func cat(path string) { f, err := os.Open(path) if err != nil { log.Fatalf("Open: %v", err) } defer f.Close() io.Copy(os.Stdout, f) } func main() { path := filepath.Join(tempDir, "writedata.txt") if err := atomicfile.WriteData(path, []byte("99 Luftballons"), 0600); err != nil { log.Fatalf("WriteData: %v", err) } cat(path) }
Output: 99 Luftballons
Types ¶
type File ¶
type File struct {
// contains filtered or unexported fields
}
A File is a temporary file that implements io.Writer and io.ReaderFrom. When a File is successfully closed, it is atomically renamed to its target. Calling File.Cancel causes the file to be discarded without renaming.
func New ¶
New constructs a new writable File with the given permissions.
When the file is successfully closed, it will be renamed to target. If the close fails, or if the file is cancelled, the file is discarded.
New reports an error if target already exists and is not a plain file.
Example ¶
package main import ( "fmt" "io" "log" "os" "path/filepath" "github.com/creachadair/atomicfile" ) var tempDir string func cat(path string) { f, err := os.Open(path) if err != nil { log.Fatalf("Open: %v", err) } defer f.Close() io.Copy(os.Stdout, f) } func main() { path := filepath.Join(tempDir, "new.txt") f, err := atomicfile.New(path, 0600) if err != nil { log.Fatalf("New: %v", err) } defer f.Cancel() fmt.Fprintln(f, "Hello, world!") if err := f.Close(); err != nil { log.Fatalf("Close: %v", err) } cat(path) }
Output: Hello, world!
func (*File) Cancel ¶
func (f *File) Cancel()
Cancel closes the temporary associated with f and discards it. It is safe to call Cancel even if File.Close has already succeeded; in that case the cancellation has no effect.
Example ¶
package main import ( "fmt" "io" "log" "os" "path/filepath" "github.com/creachadair/atomicfile" ) var tempDir string func cat(path string) { f, err := os.Open(path) if err != nil { log.Fatalf("Open: %v", err) } defer f.Close() io.Copy(os.Stdout, f) } func main() { path := filepath.Join(tempDir, "cancel.txt") if err := os.WriteFile(path, []byte("left right\n"), 0600); err != nil { log.Fatalf("WriteFile: %v", err) } cat(path) f, err := atomicfile.New(path, 0640) if err != nil { log.Fatalf("New: %v", err) } fmt.Fprintln(f, "Hello, world!") f.Cancel() // After cancellation, Close reports an error. if err := f.Close(); err == nil { log.Fatal("Close should have reported an error") } // The target path should not have been modified. cat(path) }
Output: left right left right
func (*File) Close ¶
Close closes the temporary file associated with f and renames it to the designated target. If closing the file fails, or if the rename fails, the temporary file is unlinked before Close returns.
func (*File) ReadFrom ¶ added in v0.3.1
ReadFrom implements the io.ReaderFrom interface to the underlying file.