2026年2月11日水曜日

【Java進化史 第5回】Java7 - NIO.2 ― Fileで戦った俺たちは、なぜ疲れていたのか

【Java進化史 第5回】NIO.2 ― Fileで戦った俺たちは、なぜ疲れていたのか

Java6までしか知らない50代が、Java7以降をやり直すシリーズ。

今回は Java7で導入された NIO.2(java.nio.file) を扱う。


■ あの頃、ファイル操作は「共通処理」だった

昔、ファイル操作はすべて共通処理にしていた。
ディレクトリ再帰、コピー、削除、存在チェック。
全部、自分たちで書いた。
テストも自分たちでやった。

例外処理も、ログも、バッファサイズも、全部。

正直、たいへんだった。

でも当時は、それが「実力」だと思っていた。


■ Java6以前 ― Fileクラスの世界


▼ 再帰削除(Java6)


public static void deleteDirectory(File dir) {
    if (dir.isDirectory()) {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                deleteDirectory(file);
            }
        }
    }
    dir.delete();
}
  • listFiles() が null を返す
  • delete() は boolean を返すだけ
  • 失敗理由がわからない
  • 再帰は自分で書く

だから「共通処理」にした。
そうしないと怖かった。

▼ ファイルコピー(Java6)


public static void copy(File src, File dest) throws IOException {
    InputStream in = new FileInputStream(src);
    OutputStream out = new FileOutputStream(dest);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = in.read(buffer)) > 0) {
        out.write(buffer, 0, length);
    }
    in.close();
    out.close();
}
  • close漏れの恐怖
  • 例外時の後処理
  • バッファサイズ設計
  • テストケースの山

「File操作ユーティリティ」は、どの現場にもあったはずだ。


■ そしてJava7 ― NIO.2の登場

Java7で導入されたのが java.nio.file パッケージ
通称 NIO.2。

▼ Pathという思想


Path path = Paths.get("sample.txt");

Fileはクラス。
Pathはインターフェース。

ここに設計思想の違いがある。


▼ コピー(Java7)


Files.copy(
    Paths.get("a.txt"),
    Paths.get("b.txt"),
    StandardCopyOption.REPLACE_EXISTING
);

終わり。
共通処理、いらない。


▼ 再帰削除(Java7)


Files.walk(Paths.get("targetDir"))
     .sorted(Comparator.reverseOrder())
     .forEach(p -> {
         try {
             Files.delete(p);
         } catch (IOException e) {
             e.printStackTrace();
         }
     });
  • 再帰を意識しない
  • APIが責任を持つ
  • 例外が明確

■ NIO.2の「2」の意味

NIO(Java1.4)は Non-blocking IO。
だが NIO.2 の本質は非同期ではない。

File APIの再設計 である。

Fileクラスは拡張性が低く、例外設計も弱く、 シンボリックリンク対応も不十分だった。

だから、作り直した。


■ 思ったこと

あの頃、俺たちはファイル操作を「共通化」していた。

それは技術力の証だと思っていた。

でも違った。

足りなかったのは俺たちじゃない。
足りなかったのはAPIだった。


■ まとめ

項目 Java6以前 Java7以降
再帰処理 自分で実装 Files.walk
コピー ストリーム手書き Files.copy
削除 boolean戻り値 IOException
設計思想 クラス中心 インターフェース中心

NIO.2は単なる便利機能ではない。
設計思想の転換点だった。




0 件のコメント:

コメントを投稿

【Java進化史 第10回】Java8 〜あのPermGenはどこへ消えた〜

【Java進化史 第10回】Java8 〜あのPermGenはどこへ消えた〜 昔、意味も分からず書いていたオプションがある。 -XX:MaxPermSize=256m 足りなければ増やす。 512m。 1024m。 それでも、死ぬ。 java.l...