Question

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);
}
Was it helpful?

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)

OTHER TIPS

Why not just invoke the system directly:

> system('mv /tmp/RtmpK4k1Ju/oldname /home/jeroen/newname')  
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top