R: Creates a file atomically

createFileAtomically {R.utils} | R Documentation

## Creates a file atomically

### Description

Creates a file atomically by first creating and writing to a temporary file which is then renamed.

### Usage

    ## Default S3 method:
    createFileAtomically(filename, path=NULL, FUN, ..., skip=FALSE, overwrite=FALSE,
      backup=TRUE, verbose=FALSE)

### Arguments

`filename` | The filename of the file to create.
`path` | The path to the file.
`FUN` | A `function` that creates and writes to the pathname that is passed as the first argument. This pathname is guaranteed to be a non-existing temporary pathname.
`...` | Additional arguments passed to `pushTemporaryFile`() and `popTemporaryFile`().
`skip` | If `TRUE` and a file with the same pathname already exists, nothing is done/written.
`overwrite` | If `TRUE` and a file with the same pathname already exists, the existing file is overwritten. This is also done atomically such that if the new file was not successfully created, the already original file is restored. If restoration also failed, the original file remains as the pathname with suffix `".bak"` appended.
`backup` | If `TRUE` and a file with the same pathname already exists, then it is backed up while creating the new file. If the new file was not successfully created, the original file is restored from the backup copy.
`verbose` | A `logical` or `Verbose`.

### Value

Returns (invisibly) the pathname.

### Author(s)

Henrik Bengtsson

### See Also

Internally, `pushTemporaryFile`() and `popTemporaryFile`() are used for working toward a temporary file, and `pushBackupFile`() and `popBackupFile`() are used for backing up and restoring already existing file.

### Examples

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # Create a file atomically
    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    n <- 10
    createFileAtomically("foobar.txt", FUN=function(pathname) {
      cat(file=pathname, "This file was created atomically.\n")
      cat(file=pathname, "Timestamp: ", as.character(Sys.time()), "\n", sep="")
      for (kk in 1:n) {
        cat(file=pathname, kk, "\n", append=TRUE)
        # Emulate a slow process
        if (interactive()) Sys.sleep(0.1)
      }
      cat(file=pathname, "END OF FILE\n", append=TRUE)
    }, overwrite=TRUE)

    bfr <- readLines("foobar.txt")
    cat(bfr, sep="\n")

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    # Overwrite the file atomically (emulate write failure)
    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    tryCatch({
      createFileAtomically("foobar.txt", FUN=function(pathname) {
        cat(file=pathname, "Trying to create a new file.\n")
        cat(file=pathname, "Writing a bit, but then an error...\n", append=TRUE)
        # Emulate write error
        stop("An error occured while writing to the new file.")
        cat(file=pathname, "END OF FILE\n", append=TRUE)
      }, overwrite=TRUE)
    }, error = function(ex) {
      print(ex$message)
    })

    # The original file was never overwritten
    bfr2 <- readLines("foobar.txt")
    cat(bfr2, sep="\n")
    stopifnot(identical(bfr2, bfr))

    # The partially temporary file remains
    stopifnot(isFile("foobar.txt.tmp"))
    bfr3 <- readLines("foobar.txt.tmp")
    cat(bfr3, sep="\n")

    file.remove("foobar.txt.tmp")

[Package R.utils version 2.7.0 Index]