ファイルやディレクトリをコピーする(Files.copy)

Files クラスで用意されている copy メソッドを使用することで、指定したファイルやディレクトリをコピーすることができます。ここでは Java を使ってファイルをコピーする方法について解説します。

※ コピーではなく移動する場合は「ファイルやディレクトリを移動する(Files.move)」を参照してください。

(Last modified: )

ファイルをコピーする

ファイルをコピーするには Files クラスで用意されている copy メソッドを使用します。 copy メソッドはクラスメソッドです。書式は次のとおりです。

public static Path copy(Path source, Path target, CopyOption... options) throws IOException

パラメータ:
source - コピーするファイルへのパス
target - ターゲット・ファイルへのパス(ソース・パスとは異なるプロバイダに関連付けられている場合がある)
options - コピーをどのように実行するべきかを指定するオプション

戻り値:
ターゲット・ファイルへのパス

例外:
UnsupportedOperationException - サポートされないコピー・オプションが配列に含まれる場合
FileAlreadyExistsException - ターゲット・ファイルは存在するけれども、REPLACE_EXISTINGオプションが指定されていないために置換できない場合(オプションの固有例外)
DirectoryNotEmptyException - REPLACE_EXISTINGオプションが指定されているけれども、空でないディレクトリであるために置換できない場合(オプションの固有例外)
IOException - 入出力エラーが発生した場合
SecurityException - デフォルト・プロバイダで、セキュリティ・マネージャがインストールされている場合は、checkReadメソッドが呼び出されてソース・ファイルへの読取りアクセスがチェックされ、checkWriteメソッドが呼び出されてターゲット・ファイルへの書込みアクセスがチェックされます。 シンボリック・リンクがコピーされる場合は、セキュリティ・マネージャが呼び出されてLinkPermission("symbolic")がチェックされます。

1 番目の引数にコピー元のファイルを表す Path オブジェクトを指定します。 2 番目の引数にコピー先のファイルを表す Path オブジェクトを指定します。省略可能な 3 番目の引数については後ほど解説します。

※ Path オブジェクトを使ってファイルやディレクトリを表す方法については「Pathオブジェクトを使ってファイルやディレクトリを表す」を参照されてください。

基本的な使い方は次のようになります。最初にファイルをコピーする場合です。

Path p1 = Paths.get("src/file1.txt");
Path p2 = Paths.get("dest/file2.txt");

try{
  Files.copy(p1, p2);
}catch(IOException e){
  System.out.println(e);
}

カレントディレクトリの下にある src ディレクトリの中の file1.txt ファイルをコピーし、カレントディレクトリの下の dest ディレクトリの中に file2.txt という名前でファイルを作成します。

この時、コピー先のファイルが既に存在していた場合は java.nio.file.FileAlreadyExistsException 例外が発生します。コピー先のファイル名と名前の同じディレクトリが存在していた場合も同じです。

次にディレクトリのコピーを行う場合です。

Path p1 = Paths.get("src");
Path p2 = Paths.get("dest");

try{
  Files.copy(p1, p2);
}catch(IOException e){
  System.out.println(e);
}

ディレクトリをコピー元として指定した場合、コピーされるのはディレクトリとなりコピー先に指定したディレクトリが作成されます。ただしコピー元のディレクトリの中にあるファイルはコピーされないので、単にコピー先のディレクトリが作成されるのと変わりがありません。

この時、コピー先のディレクトリが既に存在している場合は java.nio.file.FileAlreadyExistsException 例外が発生します。コピー先のディレクトリ名と同じ名前のファイルが存在していた場合も同じです。

サンプルコード

それでは簡単なサンプルプログラムを作って試してみます。テキストエディタで次のように記述したあと、 JSample11-1.java という名前で保存します。

import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;

class JSample11_1{
  public static void main(String[] args){
    Path p1 = Paths.get("C:/code/java/file/doc/memo.txt");
    Path p2 = Paths.get("C:/code/java/file/doc/memo.back");
    Path p3 = Paths.get("C:/code/java/file/doc/src");
    Path p4 = Paths.get("C:/code/java/file/doc/dest");

    try{
      Files.copy(p1, p2);
      Files.copy(p3, p4);
    }catch(IOException e){
      System.out.println(e);
    }
  }
}

プログラムの実行前、 C:\code\java\file\doc ディレクトリの中には次のように memo.txt ファイルと src ディレクトリが作成されていました。

ファイルをコピーする(1)

src ディレクトリの中には report.txt ファイルが作成されています。

ファイルをコピーする(2)

コンパイルを行います。

javac -encoding UTF-8 JSample11_1.java

その後で、次のように実行してください。

java JSample11_1

ファイルをコピーする(3)

ファイルおよびディレクトリがコピーされました。あらためて C:\code\java\file\doc ディレクトリの中を確認してみると、 memo.txt がコピーされて memo.back が作成され、 src ディレクトリがコピーされて dest ディレクトリが作成されました。

ファイルをコピーする(4)

ただしディレクトリのコピーは指定した名前のディレクトリが作成されるだけで、コピー元のディレクトリに格納されていたファイルはコピーされません。作成された dest ディレクトリの中を確認しても空のままとなります。

ファイルをコピーする(5)

コピー先のファイルやディレクトリが既に作成されている状態で copy メソッドを実行すると例外が発生します。先ほどのプログラムをもう一度実行すると、コピー先に指定しているファイルが既に存在しているので例外が発生しました。

ファイルをコピーする(6)

REPLACE_EXISTINGオプションを付けてコピーする

copy メソッドを実行するときに、 3 番目の引数に REPLACE_EXISTING を設定すると、コピー先のファイルが既に存在していた場合に例外を発生させるのではなくコピー元のファイルをコピーした新しいファイルで置き換えます。

具体的には次のように記述します。

Path p1 = Paths.get("src/file1.txt");
Path p2 = Paths.get("dest/file2.txt");

try{
  Files.copy(p1, p2, REPLACE_EXISTING);
}catch(IOException e){
  System.out.println(e);
}

※ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; が必要です。

REPLACE_EXISTING オプションを指定した場合、コピー先である dest\file2.txt ファイルが既に存在していた場合、コピー元である src\file1.txt をコピーしたファイルで置き換えられます。

この時、コピー先に指定したファイル名と同じディレクトリが存在した場合、ディレクトリをコピー元である src\file1.txt をコピーしたファイルで置き換えられます。ただしディレクトリが空ではなくディレクトリの中に何らかのファイルが格納されている場合には java.nio.file.DirectoryNotEmptyException 例外が発生します。

サンプルコード

それでは簡単なサンプルプログラムを作って試してみます。テキストエディタで次のように記述したあと、 JSample11-2.java という名前で保存します。

import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

class JSample11_1{
  public static void main(String[] args){
    Path p1 = Paths.get("C:/code/java/file/doc/memo.txt");
    Path p2 = Paths.get("C:/code/java/file/doc/memo.back");

    try{
      Files.copy(p1, p2, REPLACE_EXISTING);
    }catch(IOException e){
      System.out.println(e);
    }
  }
}

プログラムの実行前、 C:\code\java\file\doc ディレクトリの中には次のように memo.txt ファイルと memo.back ファイルが作成されていました。

REPLACE_EXISTINGオプションを付けてコピーする(1)

コンパイルを行います。

javac -encoding UTF-8 JSample11_2.java

その後で、次のように実行してください。

java JSample11_2

REPLACE_EXISTINGオプションを付けてコピーする(2)

今回コピー先のファイルとして指定した memo.back ファイルは既に存在していましたが、プログラムを実行しても例外は発生せずに memo.txt をコピーしたファイルで memo.back が置き換えられました。

REPLACE_EXISTINGオプションを付けてコピーする(3)

-- --

Java を使ってファイルをコピーする方法について解説しました。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。