atomicfile

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 21, 2025 License: MIT Imports: 5 Imported by: 0

README

atomicfile

A Go library to help create files atomically.

The file is created only if all writes succeeded.

To learn how to use it:

example usage

package main

import (
	"fmt"
	"log"
	"os"

	"github.com/kjk/atomicfile"
)

func writeToFileAtomically(filePath string, data []byte) error {
	f, err := atomicfile.New(filePath)
	if err != nil {
		return err
	}

	// ensure that if there's a panic or early exit due to
	// error, the file will not be created
	// RemoveIfNotClosed() after Close() is a no-op
	defer f.RemoveIfNotClosed()

	_, err = f.Write(data)
	if err != nil {
		return err
	}
	return f.Close()
}

func main() {
	fileName := "foo.txt"
	data := []byte("hello\n")
	err := writeToFileAtomically(fileName, data)
	if err != nil {
		fmt.Printf("writeToFileAtomically failed with '%s'\n", err)
		return
	}
	st, err := os.Stat(fileName)
	if err != nil {
		log.Fatalf("os.Stat('%s') failed with '%s'\n", fileName, err)
	}
	fmt.Printf("Wrote to file '%s' atomically. Size of file: %d bytes\n", fileName, st.Size())
	_ = os.Remove(fileName)
}

Documentation

Overview

To write to files in a robust way we should:

- handle error returned by `Close()`

- handle error returned by `Write()`

- remove partially written file if `Write()` or `Close()` returned an error

This logic is non-trivial.

Package atomicfile makes it easy to get this logic right:

func writeToFileAtomically(filePath string, data []byte) error {
	w, err := atomicfile.New(filePath)
	if err != nil {
		return err
	}
	// calling Close() twice is a no-op
	defer w.Close()

	_, err = w.Write(data)
	if err != nil {
		return err
	}
	return w.Close()
}

To learn more see https://presstige.io/p/atomicfile-22143bf788b542fda2262ca7aee57ae4

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrCancelled is returned by calls subsequent to Cancel()
	ErrCancelled = errors.New("cancelled")
)

Functions

This section is empty.

Types

type File

type File struct {
	// contains filtered or unexported fields
}

File allows writing to a file atomically i.e. if the while file is not written successfully, we make sure to clean things up

func New

func New(path string) (*File, error)

New creates new File

func (*File) Close

func (f *File) Close() error

Close closes the file. Can be called multiple times to make it easier to use via defer

func (*File) RemoveIfNotClosed

func (f *File) RemoveIfNotClosed()

RemoveIfNotClosed removes the temp file if we didn't Close the file yet. Destination file will not be created. Use it with defer to ensure cleanup in case of a panic on the same goroutine that happens before Close. RemoveIfNotClosed after Close is a no-op.

func (*File) Seek

func (f *File) Seek(offset int64, whence int) (ret int64, err error)

func (*File) SetWriteDeadline

func (f *File) SetWriteDeadline(t time.Time) error

func (*File) Sync

func (f *File) Sync() error

func (*File) Truncate

func (f *File) Truncate(size int64) error

func (*File) Write

func (f *File) Write(d []byte) (int, error)

Write writes data to a file

func (*File) WriteAt

func (f *File) WriteAt(b []byte, off int64) (n int, err error)

func (*File) WriteString

func (f *File) WriteString(s string) (n int, err error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL