Attempt first to make a hardlink. If that fails, try to make a symlink (on non-windows systems and symlink = TRUE). If that fails, copy the file.

linkOrCopy(
  from,
  to,
  symlink = TRUE,
  verbose = getOption("reproducible.verbose", 1)
)

Arguments

from, to

Character vectors, containing file names or paths. to can alternatively be the path to a single existing directory.

symlink

Logical indicating whether to use symlink (instead of hardlink). Default FALSE.

verbose

Numeric, -1 silent (where possible), 0 being very quiet, 1 showing more messaging, 2 being more messaging, etc. Default is 1. Above 3 will output much more information about the internals of Caching, which may help diagnose Caching challenges. Can set globally with an option, e.g., options('reproducible.verbose' = 0) to reduce to minimal

Value

This function is called for its side effects, which will be a file.link is that is available or file.copy if not (e.g., the two directories are not on the same physical disk).

Note

Use caution with files-backed objects (e.g., rasters). See examples.

Author

Alex Chubaty and Eliot McIntire

Examples

library(datasets)
library(magrittr)
#> 
#> Attaching package: ‘magrittr’
#> The following object is masked from ‘package:raster’:
#> 
#>     extract
library(raster)

tmpDir <- file.path(tempdir(), "symlink-test") %>%
  normalizePath(winslash = '/', mustWork = FALSE)
dir.create(tmpDir)

f0 <- file.path(tmpDir, "file0.csv")
write.csv(iris, f0)

d1 <- file.path(tmpDir, "dir1")
dir.create(d1)
write.csv(iris, file.path(d1, "file1.csv"))

d2 <- file.path(tmpDir, "dir2")
dir.create(d2)
f2 <- file.path(tmpDir, "file2.csv")

## create link to a file
linkOrCopy(f0, f2)
#> Hardlinked version of file(s) created at: /tmp/Rtmp56YhgE/symlink-test/file2.csv, which point(s) to /tmp/Rtmp56YhgE/symlink-test/file0.csv; no copy was made.
#> [1] TRUE
file.exists(f2) ## TRUE
#> [1] TRUE
identical(read.table(f0), read.table(f2)) ## TRUE
#> [1] TRUE

## deleting the link shouldn't delete the original file
unlink(f0)
file.exists(f0) ## FALSE
#> [1] FALSE
file.exists(f2) ## TRUE
#> [1] TRUE

## using rasters and other file-backed objects
f3a <- system.file("external/test.grd", package = "raster")
f3b <- system.file("external/test.gri", package = "raster")
r3a <- raster(f3a)
f4a <- file.path(tmpDir, "raster4.grd")
f4b <- file.path(tmpDir, "raster4.gri")
linkOrCopy(f3a, f4a) ## hardlink
#> Hardlinked version of file(s) created at: /tmp/Rtmp56YhgE/symlink-test/raster4.grd, which point(s) to /home/runner/work/_temp/Library/raster/external/test.grd; no copy was made.
#> [1] TRUE
linkOrCopy(f3b, f4b) ## hardlink
#> Hardlinked version of file(s) created at: /tmp/Rtmp56YhgE/symlink-test/raster4.gri, which point(s) to /home/runner/work/_temp/Library/raster/external/test.gri; no copy was made.
#> [1] TRUE
r4a <- raster(f4a)

isTRUE(all.equal(r3a, r4a)) # TRUE
#> [1] TRUE

## cleanup
unlink(tmpDir, recursive = TRUE)