ホーム › ファイルI/O › F-03b: java.nio.file ファイル操作
F-03b: java.nio.file によるファイル操作
Java 7 で導入された NIO.2(java.nio.file)パッケージは、 従来の java.io.File クラスより直感的で強力なファイル操作を提供します。 現代の Java 開発では NIO.2 の Files クラスを使うのが一般的です。
なぜ NIO.2 を使うのか
旧来の java.io.File クラスには以下の問題がありました。
- メソッドの戻り値が
booleanのみで、失敗した理由がわからない - 例外を投げないため、エラーが発生しても無言で失敗する
- シンボリックリンクや属性へのアクセスができない
NIO.2 の Files クラスは失敗時に明示的な例外を投げるため、 エラーハンドリングがしやすく、コードの意図も明確になります。
主要な API(Java バージョン別)
| API | 追加バージョン | 説明 |
|---|---|---|
| Files.write / readAllLines / readAllBytes / copy / move / delete | Java 7+ | 基本的なファイル操作 |
| Files.list / walk | Java 8+ | ディレクトリ列挙(Stream を返す) |
| Files.writeString / readString | Java 11+ | 文字列をそのまま読み書き |
| Files.mismatch | Java 12+ | 2ファイルの比較 |
| Path.of() | Java 11+ | Paths.get() の簡略版 |
サンプルコード
よくあるミス・注意点
⚠️ Files.list() / Files.walk() は必ず try-with-resources で閉じる
Files.list() と Files.walk() は Stream<Path> を返しますが、 内部でファイルディスクリプタを保持しているため、必ず try-with-resources で閉じる必要があります。 閉じないとファイルディスクリプタが枯渇する可能性があります。
// NG: close されない
Stream<Path> stream = Files.list(dir);
stream.forEach(System.out::println);
// OK: try-with-resources で確実に close
try (Stream<Path> stream = Files.list(dir)) {
stream.forEach(System.out::println);
}📌 Files.delete() は空のディレクトリしか削除できない
Files.delete() は空でないディレクトリを渡すと DirectoryNotEmptyException をスローします。 ディレクトリを再帰削除したい場合は Files.walk() で降順に処理するか、 Apache Commons IO などの外部ライブラリを使います。
📌 java.io.File と java.nio.file.Path は相互変換できる
古い API と新しい API を混在させる必要がある場合は変換して対応できます。
File file = new File("example.txt");
Path path = file.toPath(); // File → Path
Path path2 = Path.of("example.txt");
File file2 = path2.toFile(); // Path → Fileテストする観点
- 存在しないファイルを読もうとすると
NoSuchFileExceptionがスローされるか - 存在しない中間ディレクトリに
Files.write()すると例外になるか(createDirectories()が先に必要) - 空でないディレクトリを
Files.delete()するとDirectoryNotEmptyExceptionが発生するか - 書き込んだ内容をそのまま読み返すと一致するか(ラウンドトリップテスト)
- UTF-8 の日本語を含むファイルが正しく読み書きできるか
Files.copy()でREPLACE_EXISTINGを指定しない場合、既存ファイルがあると例外になるか