概要

Java 7 で導入された java.nio.file パッケージは、従来の java.io.File に比べてファイル操作を簡潔かつ安全に書けるようになりました。Java 11 では Files.readString() / writeString() が追加され、テキストファイルの読み書きが1行で完結します。しかし実務では「どのメソッドを使えばいいのか」「java.io と混在するプロジェクトでどう使い分けるのか」という迷いが生じることも多いです。この記事では、Files クラスの主要メソッドをユースケース別に整理し、コピー・移動・属性取得・ディレクトリ操作までを実務で使える形にまとめます。

使いどころ

バッチ処理でファイルを所定のディレクトリにコピー・移動し、処理済みフォルダへ振り分ける

設定ファイルやテンプレートを Files.readString() で一括読み込みし、変数を置換して出力する

指定ディレクトリ内のファイルを一覧取得し、拡張子やサイズで絞り込んでバッチ対象を決定する

コード例

NIO Files によるファイル操作
import java.io.IOException;

public class NioFileOperations {

    public static void main(String[] args) throws IOException {

        var file = Path.of("sample_nio.txt");
        var content = "1行目: NIO サンプル\n2行目: Files API\n3行目: UTF-8 デフォルト";
        Files.writeString(file, content);

        var text = Files.readString(file);
        System.out.println("読み込み:\n" + text);

        var dir = Path.of("work/output");
        Files.createDirectories(dir);

        var copy = dir.resolve("sample_copy.txt");
        Files.copy(file, copy, StandardCopyOption.REPLACE_EXISTING);

        var moved = dir.resolve("sample_moved.txt");
        Files.move(copy, moved, StandardCopyOption.REPLACE_EXISTING);

        System.out.println("サイズ: " + Files.size(moved) + " bytes");
        var attrs = Files.readAttributes(moved, BasicFileAttributes.class);
        System.out.println("更新日時: " + attrs.lastModifiedTime());

        try (var stream = Files.list(dir)) {
            stream.forEach(p -> System.out.println("  " + p.getFileName()));
        }

        Files.delete(moved);
        Files.delete(dir);
        Files.delete(Path.of("work"));
        Files.delete(file);
    }
}

Java 8 / 17 / 21 の完全なサンプルコードは GitHub リポジトリ で確認できます。

Version Coverage

Files.readString() / writeString()(Java 11+)で1行読み書きが可能。Path.of()(Java 11+)でパス生成も簡潔になる。

Java 17
// Java 17: Path.of() + readString() で簡潔に
var file = Path.of("sample.txt");
var text = Files.readString(file); // UTF-8 がデフォルト
Files.writeString(file, "新しい内容");

Library Comparison

java.nio.file.FilesJava 7 以降の標準 API。ファイル操作全般をカバーし、外部依存なしで使える。大容量ファイルの一括読み込みはメモリに注意。ストリーム処理への切り替え判断が必要。
java.io.Fileレガシーコードとの互換性が必要な場合。エラー情報が乏しく(boolean 返却)、例外ベースの NIO のほうが原因特定しやすい。
Apache Commons IOFileUtils.copyDirectory() など、ディレクトリ単位のコピーや再帰削除が必要な場合。外部依存が増える。Files.walk() + Files.copy() の組み合わせで代替可能な場面も多い。

注意点

Files.readString() / readAllLines() は全内容をメモリに読み込むため、大容量ファイルには不向き。数MB を超える場合は Files.lines() でストリーム処理すること。

Files.list() / Files.find() は Stream を返すが、内部でディレクトリハンドルを保持している。必ず try-with-resources で close すること。

Files.move() はファイルシステムをまたぐ場合にコピー+削除にフォールバックする。処理中に電源断が起きるとファイルを失う可能性がある。

Path.of() は Java 11 以降。Java 8 では Paths.get() を使う。

FAQ

java.io.File と java.nio.file.Path のどちらを使うべきですか。

新規コードでは Path を推奨します。File.toPath() で変換できるため、既存コードとの共存も容易です。

Files.readString() のデフォルト文字コードは何ですか。

UTF-8 です。別の文字コードを使う場合は第2引数で Charset を指定してください。Shift_JIS のファイルを読む場合は Charset.forName("Shift_JIS") を渡します。

ディレクトリを中身ごと削除するにはどうしますか。

Files.walk() で深い順にソートし、Files.delete() で1つずつ削除するのが標準的な方法です。Files.delete() は空でないディレクトリには使えません。

関連書籍

この記事のテーマをさらに深く学びたい方へ。

※ Amazon アソシエイトリンクを含みます