Windowsで大量のファイルをコピーするときの対処法

みんな大好きRobocopyの話です。コピー元から大量のファイルをコピーするときに、Ctrl+Cよりはるかに早く、下位フォルダや指定日付以降限定とか、コピー元で削除されたファイルをコピー先でも削除してミラーリングを保つとかが簡単に行えます。ちょっとした工夫で \\192.168.1.201\WORK のようなNASや別PCにあるファイルをコピー元、コピー先に指定することもできます。

RobocopyはWindowsに普通に入っているコマンドツールで、めちゃめちゃ高性能です。最近は新しいPCを購入してもデータはクラウドだから写真や音楽ファイルの大量コピーとか少なくなったかもしれませんが、こういうのもあるよ、と知っているといろいろ役立つと思いますので、頭の片隅に「ロボコピー」という手段があることを留めておくと、幸せになれると思います。

ここでお約束。Robocopyはコピー先の指定を誤って使用すると、そこにあったフォルダ、ファイルをすべて削除してしまう場合があります。利用する際には必ずテストのフォルダを用意して十分に検証を行ってから本番設定にのぞんでください。Robocopyの利用は自己責任で。利用したことでなにか損害があったとしても、こちらでは一切保証も対応もコメントも行えませんのであらかじめご了承ください。

まずはコマンドプロンプトで確認

コマンドはそのままま「robocopy」です。簡単な使い方が出てきます。コマンドに続けてコピー元、コピー先の順番でディレクトリを指定します。あらかじめテスト用のフォルダ c:\tmp\A と c:\tmp\B を用意して以下のように指定しました。Aがコピー元、Bがコピー先 です。くどいようですが、必ず空っぽのテスト用フォルダを自分で用意してから試してください。

robocopy c:\tmp\A c:\tmp\B

フォルダの中にはまだ何もファイルを入れていないので、実際のコピーはされていませんが、下のほうにファイルがいくつコピーされたかなどの情報が出てきます。

注目するべきは「オプション」という表示です。ロボコピーは何もオプション指定をしない場合、自動的に「*.* /DCOPY:DA /COPY:DAT /R:1000000 /W:30」というオプションが指定されます。

これがどういう意味かというと、「そのフォルダにあるすべての拡張子のファイルをコピーします。ディレクトリはデータと属性、ファイルはデータと属性とタイムスタンプをコピーします。リトライは1000000回行い、再試行の際は30秒待機します」という内容です。

上記のような画面が表示されていれば、Robocopyを使えるということです。ちなみに、Robocopyの実態はc:\windows\system32の中にあります。

バッチファイルで実行する

コピー元のc:\tmp\A にあらかじめテスト用のダミーファイルとフォルダを用意しておきました。

コマンドプロンプトで手打ちしていると、誤ってあらぬフォルダのデータを削除してしまってはいけませんので、ここからはバッチファイルを作ります。バッチファイルとはクリックするだけでその中に書いてある動作をまとめて実行してくれる拡張子が.batのファイルのことです。といっても難しいものではなく、ただのテキストファイルです。

取り急ぎ、デスクトップに作成してみましょう。デスクトップの何もないところでマウスの右クリック、「新規作成」から「テキストドキュメント」をクリックしてからのテキストファイルを作成します。作成できたら拡張子をbatに変更してください。

拡張子をbatに変更します。警告ははいを選択してください。

拡張子をbatに変更したファイルは、そのままダブルクリックすると内容を実行してしまうので、中身を編集するにはファイルの上で右クリック、「編集」を選択します。最新のWindows11の場合、その他のオプションの表示の中に隠れているかもしれません。

編集するとメモ帳が開きます。上記の手順で行った場合は空っぽですので先ほどコマンドプロンプトで入力したようにrobocopyに続けてコピー元、コピー先を指定したコマンドを記載してctrl+S で保存します。

これでバッチファイルに入力した内容は、バッチファイルをダブルクリックするだけで動作するようになりました。

なんか出て実行できない?

テキストファイルを保存できてない、空のバッチファイルを実行するとこうなります。

フォルダもコピーするには

コピー先にファイルがコピーできました。ただし、フォルダはコピーされませんでした。フォルダもコピーするには /S または /E オプションを加える必要があります。

/S サブフォルダをコピーしますが、空のフォルダはコピーされません。個人的にはこちらが好みです。
/E サブフォルダをコピーします。フォルダは空でもコピーされます。

バッチファイルの後に加えて実行し、動作を把握しましょう。最後行にpauseを加えておくとコマンドプロンプトが閉じないのでどのように動作したか結果を確認できるので便利です。実行するとフォルダもコピーされましたね?

robocopy c:\tmp\A c:\tmp\B /S
pause

Bのフォルダにフォルダもコピーされましたね。

では続いて実験。Aのコピー元フォルダ側にあったファイル(ここでは「コピーするダミーファイル.txt」)を削除してから、再度バッチファイルを実行してみましょう。結果として以下のようなレポートが出てきました。

EXTRA Fileに先ほどコピー元のAフォルダで削除したファイル名があります。Extras(6つめ)のところに1がついています。その下のバイトは0です。2つのフォルダでこのファイルが異なっていたけれど、削除などの操作は行われなかったことを示します。フォルダAで消されていてもフォルダBには残ったままなことがわかります。

フォルダAにフォルダBからテキストファイルをコピーして戻し、テキストファイルを開いて内容を書き換えてからバッチファイルを実行するとどうでしょう?ファイルのタイムスタンプが変わり、新しい内容に変わっていますのでフォルダAからフォルダBに上書きされました。コピー済み1,バイト30がそれを表します。(ちょっとずれていてわかりにくいですね)/Sや/E オプションの場合は、コピー先のファイルは削除されず、フォルダAに存在したことがあるファイルが消されてもフォルダBに残るのでバックアップにはよさそうですね。

強力なミラーリング /MIRオプションを試す

今度は、フォルダAからテキストファイルを削除し、ミラーリングオプションを試してみましょう。くれぐれもいきなり本番のディレクトリで試さないでください。消えますよ!

robocopy c:\tmp\A c:\tmp\B /MIR
pause

Extrasは1、バイト30となっています。フォルダBを確認すると、フォルダAで削除したファイルが消えています。これがミラーリングです。コピー先のファイルがコピー元と全く同じになるので、うっかり大切なファイルが既にたくさんあるフォルダをコピー先に指定して実行すると、ぜんぶ消えます。ミラーリングは便利で強力な機能ですが用法を守って安全に使ってください。万が一大切なファイルを失っても責任持てませんから。

フォルダの文字化け対策

フォルダに日本語名が使われている場合、フォルダ名が文字化けしてバッチが動作しない場合があります。

これはバッチファイルがUTF-8の文字コードで書かれているのをコマンドプロンプトが解釈できないの原因です。詳しくはこちらのブログが参考になります。 手っ取り早くバッチファイルの先頭に chcp 65001 おまじないを付け加えると大体解決します。くわえてフォルダ名をダブルクォーテーションで囲っておくとスペース入りフォルダ名などによる誤動作を防止できます。

chcp 65001
robocopy "c:\tmp\えーだよ" "c:\tmp\B" /MIR
pause

別PCにあるフォルダを指定する

たとえば、 \\10.26.18.142\a にあるファイルをRobocopyをつかってミラーリングすることは可能でしょうか? できます。

robocopy "\\10.26.18.142\a" "c:\tmp\B"
pause

これでよいのですが、場合によっては指定するサーバにアクセス権が必要だったりします。そこで一時的に指定するネットワーク越しのフォルダをネットワークフォルダに指定してやります。\\10.26.18.142\a を Q:\ のように読み替えてやることができます。エクスプローラから設定もできますが、せっかくなのでコマンドプロンプトに組み込みましょう。

net use /del q:
net use q: "\\10.26.18.142\a"
robocopy "q:" "c:\tmp\B"
net use /del q:
pause

最初の net use /del q: の部分は、もしQドライブがすでにあったら指定を解除

net use q: “\\10.26.18.142\a" で、IPアドレスを指定したサーバの共有フォルダをQドライブに指定しています。ドライブは空いているドライブなら何でも構いません。ZとかYとか。

最後に処理が終わったら使ったネットワークドライブを net use /del q: で解除しています。

バッチを定期実行する

ちゃんと動くバッチファイルができたら、定期的に実行してバックアップなどの処理を行わせたいですよね。そんな時にはタスクスケジューラーを使います。検索から「タスクスケジューラ」を検索して実行しましょう。

開いたら右のほうにある「タスクの作成」をクリックします。

  • 全般タグで「名前」に適当なタスクの名前を入力します。
  • 「ユーザーがログオンしているかどうかにかかわらず実行する」を選択します。
  • 「最上位の特権で実行する」にチェックを入れます。

次に、トリガータブを開き、「新規」をクリックします。

今回は毎日よなかの23時にバックアップを実行することにしましょう。

  • 「毎日」にチェックを入れます。
  • 開始時間に23時を指定します。(初回の日付をして指定できます)
  • OKをクリックします。

「操作」タグを開き、「新規」をクリックします。

「参照」をクリックします。

先ほど作ったバッチファイルを指定します。あらかじめバッチファイルは適当な場所に移動してからここで選択したほうがよいでしょう。デスクトップにあったら誤って消してしまうかもですから。バッチファイルの末尾の「pause」は自動実行の際は必要ないので消しておいたほうがよいでしょう。

バッチファイルを指定して「OK」で決定したら、パスワードを聞いてきます。これはPCでユーザーがログアウトしていてもバッチを動かすために、ユーザーに成り代わって裏で動作するために要求されているので、実行ユーザーのパスワードを入力してやります。

これでタスクスケジューラーにバッチファイルの自動実行が登録されました。「次回の実行時刻」が予定されているのがわかります。「前回の実行結果」を見ると成功か失敗かがわかります。

最後に

ここまでrobocopyを使ったファイルの大量コピーとバックアップ、ミラーリングの方法を解説してみました。注意して使えば非常に強力なコマンドツールなので積極的に利用してみましょう。

Macで大量のファイルをコピーする方法という記事をだいぶ前に書いたのですが、アクセス数がとても多いので、調子に乗ってWindowsについても書いてみました。