2013-07-27 12 views
6

Jaka jest najbardziej niezawodna metoda przenoszenia całego katalogu z powiedzmy /tmp/RtmpK4k1Ju/oldname na /home/jeroen/newname? Najprostszym sposobem jest file.rename jednak nie zawsze działa, na przykład, gdy from i to są na różnych dyskach. W takim przypadku cały katalog musi być rekurencyjnie skopiowany.Solidna, wieloplatformowa metoda przenoszenia katalogu

Oto coś, co wymyśliłem, ale jest trochę zaangażowane i nie jestem pewien, czy będzie działać na wielu platformach. Czy istnieje lepszy sposób?

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); 
} 
+0

Nie jestem całkowicie pewien, jakie jest twoje aktualne pytanie. Dla mnie twój kod wygląda dobrze, ale nigdy nie zadeklarowałbym czegoś na platformie bez znajomości wszystkich platform, o których mówimy i testowania kodu na nich wszystkich. Czy chcesz, abyśmy przetestowali twój kod na różnych platformach raportujących wynik? Jeśli nie, to sądzę, że twój kod jest dość prosty i nie bierze w ogóle udziału, biorąc pod uwagę to, co robisz. Jedyne mniej zaangażowane rozwiązanie, jakie widziałem, zostało udzielone przez Carla Witthofta (w tym poprawki sugerowane w jego komentarzu), ale wygląda na to, że nie jest to to, czego szukasz. – mschilli

Odpowiedz

3

myślę file.copy powinna być wystarczająca.

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

Od ?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. 

oraz:

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

Z opisu o recursive wiemy from może mieć katalogi. Dlatego w powyższym kodzie wymienienie wszystkich plików przed kopiowaniem nie jest konieczne. I pamiętaj, że katalog to byłby rodzicem skopiowanego from. Na przykład po file.copy("dir_a/", "new_dir/", recursive = T), pod new_dir będzie dir_a.

Twój kod wykonał część usuwania. unlink ma ładną opcję recursive, której nie ma w przypadku file.remove.

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

... a następnie usunięcie oryginału. –

+0

Pomyślałem tylko, że oryginalny kod wypadł dobrze w tej części. : D – lcn

+0

To, czego nie lubię w przypadku 'pliku.copy' oznacza, że ​​'to' może być interpretowane jako * copy jako * lub * copy * w tym katalogu. A to zachowanie zmienia się w zależności od systemu operacyjnego i zależy od tego, czy 'to' jest istniejącym katalogiem. – Jeroen

0

Dlaczego nie wystarczy powołać system bezpośrednio:

> system('mv /tmp/RtmpK4k1Ju/oldname /home/jeroen/newname') 
+3

To nie jest tak naprawdę platforma wieloplatformowa? – Spacedman

+0

Ponadto chciałbym zminimalizować w zależności od zewnętrznych programów, które wymagają dodatkowych uprawnień. – Jeroen

+0

@ Jeroen NIGDY nie można usunąć plików w/out z poziomu podstawowego poziomu uprawnień. @spacedman - z pewnością jest to platforma wieloplatformowa dla systemów Unix, Linux, OSX i każdego, kto załadował cygwin. I na litość boską, nie jest trudno napisać strukturę if/else, która wyszukuje bieżący typ systemu operacyjnego i wykonuje odpowiednie wywołanie ("mv" w stosunku do tego, co jest stosem septyczno-wymiocinowym, którego używa CommandPrompt do przenoszenia plików na około). Stoję na stanowisku, że łatwiej jest używać wywołań systemowych niż tworzyć jakieś wymyślne obejście wewnątrz 'R'. –

Powiązane problemy