Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Robust cross-platform method of moving a directory

Tags:

r

cran

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);
}
like image 446
Jeroen Ooms Avatar asked Jul 27 '13 10:07

Jeroen Ooms


1 Answers

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)
like image 73
lcn Avatar answered Nov 04 '22 01:11

lcn