検索

キーワード


【Java】java.nio.fileパッケージの使用例②(移動・コピー、削除)

  • 公開日:2021-05-02 23:31:38
  • 最終更新日:2021-05-02 23:37:10
【Java】java.nio.fileパッケージの使用例②(移動・コピー、削除)

当記事は、【Java】java.nio.fileパッケージの使用例①(ファイルの作成、存在チェック)の続きの記事であり、java.nio.fileパッケージを使った、Java上での以下のファイル操作について解説します。

  • ファイル・ディレクトリの移動・コピー
  • ファイル・ディレクトリの削除

当記事でのサンプルコードは、前記事で作成したディレクトリやファイルを元に記述しています。

java.nio.fileパッケージの概要について知りたい方は、以下の記事を参照して下さい。

【Java】Pathオブジェクトを生成する方法(java.nio.fileパッケージ)

また、ファイル名などのディレクトリに含まれ0るファイルの一覧の取得、ファイルの属性の取得といったファイル操作は以下の記事で解説します。

【Java】java.nio.fileパッケージの使用例①(ファイルの作成、存在チェック)

【Java】java.nio.fileパッケージの使用例③(ファイル属性の取得・変更)

FileChannelを使ったファイルのコピーは、以下の記事で解説します。

【Java】FileChannelを使って高速にファイル入出力を行ってみた

ファイル・ディレクトリの移動・コピー

ファイルやディレクトリの移動にはFIlesクラスmoveメソッド、コピーにはFilesクラスcopyメソッドを使います。


ファイル・ディレクトリの移動・コピーを行うメソッド

以下のメソッドの引数のうち、CopyOptionsは、移動・コピーを行う際のオプションを指定するための可変長引数です。

また、入力ストリームからコピー、出力ストリームへコピーを行うメソッドがあります。

入出力ストリームについては、以下の記事で解説しています。

【Java】入出力ストリーム(java.ioパッケージ)

メソッド名修飾子と型説明
move(Path source, Path target, CopyOptions... options)static Pathsourceに渡したファイル・ディレクトリをtargetに渡したパスに移動します。
copy(Path source, Path target, CopyOptions... options)static Pathsourceに渡したファイル・ディレクトリをtargetに渡したパスにコピーします。
copy(InputStream in, Path target, CopyOptions... options)static longinに渡した入力ストリームから、targetに指定したパスにファイルをコピーします。
返り値は、読み取られたまたは書き込まれたバイト数です。
copy(Path source, OutputStream out)static longsourceに渡したファイルを、outに渡した出力ストリームにコピーします。
返り値は、読み取られたまたは書き込まれたバイト数です。


CopyOptionで指定できるオプションは、主に以下のようなものがあります。これらはjava.nio.file.StandardCopyOptionクラスで用意されている列挙型の定数で、StandardCopyOption.定数名という書式で呼び出すことが出来ます。

オプション名説明
REPLACE_EXISTING移動・コピー先にファイルが存在した場合に上書きを行います。ディレクトリの場合は、移動・コピー先ファイルが空でない場合に、例外DirectoryNotEmptyExceptionがスローされます。
COPY_ATTRIBUTESアクセス権や作成日時などのファイル属性もコピーします。copyメソッドでのみ指定可能です。
ATOMIC_MOVEファイルの移動に失敗した場合は、移動を行う前の状態のままになります。このように、ある操作を行う前後で、その間の状態にアクセスできない操作のことを、アトミック操作または不可分操作といいます。moveメソッドでのみ指定可能です。



moveメソッドの記述例

移動元と移動先のPathオブジェクトを以下の通りとします。

Path source = Paths.get("移動元のパス");
Path target = Paths.get("移動先のパス");

moveメソッドでファイルの移動を行います。この例では、オプションにATOMIC_MOVEを指定しています。

Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);

copyメソッドの記述例

コピー元とコピー先のPathオブジェクトを以下の通りとします。

Path source = Paths.get("コピー元のパス");
Path target = Paths.get("コピー先のパス");

copyメソッドでファイルのコピーを行います。この例では、オプションにREPLACE_EXISTINGを指定しています。

Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

FileInputStreamを使ってファイルをコピーします。

FileInputStream fis = new FileInputStream("コピー元のパス");
Files.copy(fis, target);

FileOutputStreamを使ってファイルをコピーします。

FileOutputStream fos = new FileOutputStream("コピー先のパス");
Files.copy(source, fos);


ファイルの移動を行うサンプルコード

以下のような【Java】java.nio.fileパッケージの使用例①(ファイルの作成、存在チェック)のサンプルコードを実行して生成したファイルおよびディレクトリを使います。

ディレクトリを作成するサンプルコードの結果1

ディレクトリを作成するサンプルコードの結果2

以下のサンプルコードでは、「sample.1.txt」というファイルを「aa」ディレクトリ直下に「sample2.txt」という名前に変更しながら移動させています。

public class moveCopySample {
	public static void main(String[] args) {
		//移動元のPathオブジェクトを作成します。
		Path sourcePath = Paths.get(".\\NIO\\sample1.txt");		
		//移動先のPathオブジェクトを生成します。
		Path targetPath = Paths.get(".\\NIO\\aa\\sample2.txt");		
		//移動元ファイルの存在チェックを行います。
		if (Files.exists(sourcePath)) {			
			//try節内でmoveメソッドを実行します。
			try {
				Files.move(sourcePath, targetPath);
			} catch (Exception e) {
				e.printStackTrace();
			}			
			//このメッセージが出れば、moveメソッドは正常に終了しています。
			System.out.println("ファイルの移動が正常に終了しました。");			
		}
		//移動元ファイルが存在しない場合は、メッセージを出します。
		else {
			System.out.println("移動元ファイルが存在しません。");
		}
	}
}


ファイルの移動を行うサンプルコードの実行結果

コンソールに以下のように出力されます。

ファイルの移動が正常に終了しました。

また、「NIO」ディレクトリ直下の「sample2.txt」ファイルが、「aa」ディレクトリ直下に「sample2.txt」という名前のファイルとして移動したことが確認できます。

moveメソッドを使ったサンプルコードの実行結果1

moveメソッドを使ったサンプルコードの実行結果2


ディレクトリのコピーを行うサンプルコード

上記のディレクトリ構成を前提にディレクトリの移動を行います。

public class moveDirectorySample {
	public static void main(String[] args) {
		//移動元のディレクトリを表すPathオブジェクトを作成します。
		Path sourceDirectory = Paths.get(".\\NIO\\aa");
		//移動先を表すPathオブジェクトを生成します。
		Path targetDirectory = Paths.get(".\\NIO\\bb\\dd");
		//try節中で、copyメソッドを実行します。
		//オプションにATOMIC_MOVEを渡してアトミックな移動操作を行うように指定します。
		try {
			Files.move(sourceDirectory, targetDirectory, StandardCopyOption.ATOMIC_MOVE);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


ディレクトリの移動を行うサンプルコードの実行結果

「NIO」ディレクトリ直下にあった「aa」ディレクトリが、「bb」ディレクトリ直下に、「dd」ディレクトリとして移動していることが確認できます。

また、「aa」ディレクトリ直下の「sample2.txt」ファイルも、ディレクトリと一緒にコピーされていることが確認できます。

ディレクトリを移動するサンプルコードの実行結果1

ディレクトリを移動するサンプルコードの実行結果2

ディレクトリを移動するサンプルコードの実行結果3


ファイル・ディレクトリのコピーを行うサンプルコード

先ほどのファイル・ディレクトリの移動を行うサンプルコードで生成したファイルおよびディレクトリを使います。

public class copySample {
	public static void main(String[] args) {
		//コピー元のファイルを表すPathオブジェクトを作成します。
		Path sourceFilePath = Paths.get(".\\NIO\\bb\\dd\\sample2.txt");
		//コピー先を表すPathオブジェクトを作成します。
		Path targetFilePath = Paths.get(".\\NIO\\bb\\cc\\sample3.txt");		
		//コピー元のディレクトリを表すPathオブジェクトを作成します。
		Path sourceDirectoryPath = Paths.get(".\\NIO\\bb\\dd");	
		//コピー先を表すPathオブジェクトを作成します。
		Path targetDirectoryPath = Paths.get(".\\NIO\\ee");	
		//try節中で、copyメソッドを実行します。
		try {
			//ファイルのコピーを行います。
			//オプションにREPLACE_EXISTINGを渡してファイルを上書きを行うオプションを指定しています。
			Files.copy(sourceFilePath, targetFilePath, StandardCopyOption.REPLACE_EXISTING);		
			//ディレクトリのコピーを行います。
			Files.copy(sourceDirectoryPath, targetDirectoryPath);
		} catch (Exception e) {
			e.printStackTrace();
		}	
		//InputStreamを使ったコピーのコピー先、およびOutputStreamを使ったコピーのコピー元のPathファイルを生成します。
		Path path = Paths.get(".\\NIO\\bb\\sample4.txt");	
		//InputStreamを使ってコピーを行います。
		try (FileInputStream fis = new FileInputStream(".\\NIO\\bb\\cc\\sample3.txt")) {
			Files.copy(fis, path);
		} catch (Exception e) {
			e.printStackTrace();
		}	
		//OutputStreamを使ってコピーを行います。
		try (FileOutputStream fos = new FileOutputStream(".\\NIO\\sample5.txt")) {
			Files.copy(path, fos);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


ファイル・ディレクトリのコピーを行うサンプルコードの実行結果

上記のサンプルコードを実行すると、ディレクトリは以下のような構成になります。

ファイル・ディレクトリをコピーするサンプルコードの実行結果1

ファイル・ディレクトリをコピーするサンプルコードの実行結果2

ファイル・ディレクトリをコピーするサンプルコードの実行結果3

ファイル・ディレクトリをコピーするサンプルコードの実行結果4

サンプルコードでは、「\NIO\bb\dd」ディレクトリを「\NIO\ee」ディレクトリにコピーしていますが、コピーした「ee」ディレクトリの中身は空になります。

copyメソッドでは、ディレクトリ内のファイルはコピーしませんので注意してください。

ファイル・ディレクトリをコピーするサンプルコードの実行結果5


ファイル・ディレクトリの削除

ファイルやディレクトリの削除にはFIlesクラスdeleteメソッド、またはdeleteIfExistsメソッドを使います。

ファイル・ディレクトリの削除を行うメソッド

メソッド名修飾子と型
説明
delete(Path path)static voidpathに渡したファイル・ディレクトリを削除します。ディレクトリを指定した場合は、ディレクトリが空である必要があります。
deleteIfExists(Path path)static booleanpathに渡したファイル・ディレクトが存在すれば削除します。ディレクトリを指定した場合は、ディレクトリが空である必要があります。


もし空でないディレクトリを削除しようとした場合は、例外DirectoryNotEmptyExceptionがスローされます。


deleteメソッド、deleteIfExistsメソッドの記述例

Pathオブジェクトで指定したファイルまたはディレクトリを削除します。

Path path = Paths.get("削除するファイルまたはディレクトリのパス");
Files.delete(path);

Pathオブジェクトで指定したファイルまたはディレクトリが、もし存在するなら削除します。

Path path = Paths.get("削除するファイルまたはディレクトリのパス");
Files.deleteIfExists(path);


ファイル・ディレクトリの削除を行うサンプルコード

先ほどのファイル・ディレクトリのコピーを行うサンプルコードで生成したファイルおよびディレクトリを使います。

public class deleteSample {
	public static void main(String[] args) {
		//削除したいファイルを指定
		Path filePath = Paths.get(".\\NIO\\sample5.txt");

		//削除したいディレクトリを指定
		Path dirPath1 = Paths.get(".\\NIO\\ee");

		//存在しないディレクトリを指定
		Path dirPath2 = Paths.get(".\\NIO\\ff");

		try {
			//deleteメソッドでファイルを削除
			Files.delete(filePath);

			//deleteIfexistsメソッドで、存在する空のディレクトリを指定して削除を行う
			if (Files.deleteIfExists(dirPath1)) {
				System.out.println(dirPath1 + "を削除しました。");
			} else {
				System.out.println(dirPath1 + "は存在しないファイルまたはディレクトリです。");
			}

			//deleteIfexistsメソッドで、存在しないディレクトリを指定して削除を行う
			if (Files.deleteIfExists(dirPath2)) {
				System.out.println(dirPath2 + "を削除しました。");
			} else {
				System.out.println(dirPath2 + "は存在しないファイルまたはディレクトリです。");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


ファイル・ディレクトリのコピーを行うサンプルコードの実行結果

上記のサンプルコードを実行すると、コンソールに以下のように出力されます。

.\NIO\eeを削除しました。
.\NIO\ffは存在しないファイルまたはディレクトリです。

また、ディレクトリは以下のような構成になります。

ファイル・ディレクトリを削除するサンプルコードの実行結果1

「sample5.txt」ファイルおよび「ee」ディレクトリが削除されたことが確認できると思います。

「bb」ディレクトリ以下はサンプルコードで操作を行っていないので、ディレクトリ構成に変更はありません。


まとめ

当記事では、ファイル・ディレクトリの削除およびコピーについて解説しました。

java.nio.fileパッケージjava.io.Fileクラスより高機能だと書きましたが、例えばFiles.deleteIfExistsメソッドのファイルの存在を確認してから削除するというメソッドは、java.io.Fileクラスにはなく、ファイルの存在チェックをしてから削除する必要があり、コードの記述が長くなります。

java.nio.fileパッケージを使いこなして簡潔に短くコードを書くことが出来れば、単にコーディングの時間が短くなるだけではなく、読みやすいので、デバッグや保守の際にも役に立ちますので、身に着けておくと何かと役に立ちます。


関連記事:

【Java】java.nio.fileパッケージ(NIO.2)

【Java】Pathオブジェクトを生成する方法(java.nio.fileパッケージ)

【Java】java.nio.fileパッケージの使用例①(ファイルの作成、存在チェック)

【Java】java.nio.fileパッケージの使用例③(?

【著者】

ゆうさい

フォワードソフト株式会社のエンジニア。経験はまだ浅いものの、Java、Python、JavaScriptなど様々な言語の他、クラウドやネットワーク技術を勉強しています。PythonやVBAを使った自動化で楽をするのを考えるのが好きです。 Oracle Certified Java Programmer Gold SE 11、HTML5プロフェッショナル認定試験レベル2、AWSプラクティショナーなどの情報資格を保有しています。

よく読まれている記事
【Java】JSPでタグライブラリを使う(JSTL)

【Java】JSPでタグライブラリを使う(JSTL)

こんにちは。エンジニアの新田です!ここでは、システムエンジニアとして働いている私が、システム開発手法や開発言語について紹介していこうと思います。今回は、JSPの標準タグライブラリ「JSTL」について紹介します。Javaについて勉強している方、Webアプリケーションを構築したいと思っている方の参考になれば幸いです!関連記事リンク: 【Java】JSPの基本的な構文/【Java】JSPのアクションタグ

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!そもそもStringとは何?『 String 』... Java言語において文字列のデータ型を指します。基本デ

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!Stringクラスformatメソッドの文字列整形【java.utilパッケージ】Formatterクラスfo

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者にも✅、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!文字列を扱う3つのクラス【java.langパッケージ】java.langパッケージの文字列を扱うクラスにはS

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!プリミティブ型と参照型プログラム開発では型を持った変数を使ってデータのやり取りをしますが、データ型によって仕様