2013-07-27 10 views
6

ディレクトリ全体を移動する最も堅牢な方法は、/tmp/RtmpK4k1Ju/oldnameから/home/jeroen/newnameまでです。最も簡単な方法はfile.renameですが、これは常に有効ではありません。たとえば、fromtoが異なるディスクにある場合などです。その場合、ディレクトリ全体を再帰的にコピーする必要があります。ディレクトリを移動する堅牢なクロスプラットフォームの方法

これは私が思いついたものですが、少し複雑ですが、クロスプラットフォームで動作するかどうかはわかりません。より良い方法がありますか?

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

私は完全にはわかりませんが、あなたの実際の質問は何ですか。私のコードはうまく見えますが、私たちが話しているプラ​​ットフォームを知らず、すべてのコードをテストすることなく、_cross-platform_を宣言することは決してありません。その結果をさまざまなプラットフォームでテストするようにしたいのですか?そうでなければ、あなたのコードはかなり単純明快で、あなたのことが何であるかを考慮していません。私が見る唯一の関与していないソリューションは、Carl Witthoft(彼のコメントで提案された改善を含む)によって与えられましたが、それはあなたが探しているものではないようです。 – mschilli

答えて

3

私はfile.copyは十分なものでなければならないと思います。 ?file.copyから

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

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. 

と:説明から

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

についてrecursive我々はfromディレクトリを持つことができます知っています。したがって上記のコードリストでは、コピーする前のすべてのファイルは不要です。そして、toディレクトリがコピーされたfromの親であることを覚えておいてください。たとえば、file.copy("dir_a/", "new_dir/", recursive = T)の後にnew_dirの下にdir_aがあります。

あなたのコードは削除部分をかなりうまく行っています。 unlinkrecursiveオプションがあります。file.removeはありません。

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

...続いてオリジナルを削除します。 –

+0

ちょうど元のコードがその部分でうまくいったと思った。 :D – lcn

+0

「ファイルについて気に入らないもの。これは 'to 'が* dirの* copy as *または* copyとして解釈されることができるということです。そして、この動作はOSによって変化し、 'to 'が既存のディレクトリであるかどうかによって変わります。 – Jeroen

0

理由だけではなく、直接、システムを起動していない:

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

それは本当にクロスプラットフォームではないのですか? – Spacedman

+0

さらに、私は追加の特権を必要とする外部プログラムに応じて最小限に抑えたいと思います。 – Jeroen

+0

@ Jeroenあなたは基本的な特権レベルを持つw/outファイルを決して削除することはできません。 @spacedman - Unix、Linux、OSX、そしてCygwinをロードしている人にとってはクロスプラットホームです。とにかく、現在のOSの種類を調べ、適切な呼び出しを行うif/else構造を書くことは難しいことではありません( 'mv'とCommandPromptがファイルを移動するために使用するseptic-vomit-pile周囲)。 'R'の中でいくつかのすばらしい回避策を作るよりも、システムコールを使う方が簡単だという私の立場に立っています。 –

関連する問題