Robust cross-platform method of moving a directory

cran, r

Solution

I think `file.copy` shall be sufficient.

file.copy(from, to, overwrite = recursive, recursive = FALSE,
          copy.mode = TRUE)

From `?file.copy`:

from, to: character vectors, containing file names or paths.  For
         ‘file.copy’ and ‘file.symlink’ ‘to’ can alternatively
         be the path to a single existing directory.

and:

recursive: logical.  If ‘to’ is a directory, should directories in
          ‘from’ be copied (and their contents)?  (Like ‘cp -R’ on
          POSIX OSes.)

From the description about `recursive` we know `from` can have directories. Therefore in your above code listing all files before copy is unnecessary. And just remember the `to` directory would be the parent of the copied `from`. For example, after `file.copy("dir_a/", "new_dir/", recursive = T)`, there'd be a `dir_a` under `new_dir`.

Your code have done the deletion part pretty well. `unlink` has a nice `recursive` option, which `file.remove` doesn't.

unlink(x, recursive = FALSE, force = FALSE)

Problem

What is the most robust method to move an entire directory from say `/tmp/RtmpK4k1Ju/oldname` to `/home/jeroen/newname`? The easiest way is `file.rename` however this doesn't always work, for example when `from` and `to` are on different disks. In that case the entire directory needs to be recursively copied. Here is something I came up with, however it's a bit involved, and I'm not sure it will work cross-platform. Is there a better way? ``` dir.move <- function(from, to){ stopifnot(!file.exists(to)); if(file.rename(from, to)){ return(TRUE) } stopifnot(dir.create(to, recursive=TRUE)); setwd(from) if(all(file.copy(list.files(all.files=TRUE, include.dirs=TRUE), to, recursive=TRUE))){ #success! unlink(from, recursive=TRUE); return(TRUE) } #fail! unlink(to, recursive=TRUE); stop("Failed to move ", from, " to ", to); } ```

Original source