0Pricing
Java Academy · レッスン

Files.walk によるディレクトリツリーの走査

Files.walk でファイルを再帰的に一覧表示し、拡張子で絞り込み、ディレクトリサイズを計算します。

「Files.walk によるディレクトリツリーの走査」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

Files.walk の概要

Files.walk(startPath) は、指定したパスを起点として、すべてのファイルとディレクトリを再帰的に列挙する遅延 Stream<Path> を返します。深さ優先で走査し、開始パス自体も含みます。

import java.nio.file.*;
import java.util.stream.*;

try (Stream<Path> stream = Files.walk(Path.of("/home/user/projects"))) {
    stream.forEach(System.out::println);
} // stream and underlying resources closed automatically

深さの制限

深い再帰を防ぐために、最大深度を指定します:

Path root = Path.of("/home/user/projects");

// Only immediate children (depth 1)
try (var stream = Files.walk(root, 1)) {
    stream.filter(p -> !p.equals(root)) // exclude start path
          .forEach(System.out::println);
}

ファイル種別によるフィルタリング

Files.isRegularFile() または Files.isDirectory() と組み合わせてフィルタリングします:

Path root = Path.of(".");

try (var stream = Files.walk(root)) {
    long fileCount = stream
        .filter(Files::isRegularFile)
        .count();
    System.out.println("Files: " + fileCount);
}

拡張子によるフィルタリング

特定の拡張子を持つすべてのファイルを検索します:

try (var stream = Files.walk(Path.of("/src"))) {
    List<Path> javaFiles = stream
        .filter(Files::isRegularFile)
        .filter(p -> p.toString().endsWith(".java"))
        .collect(Collectors.toList());
    javaFiles.forEach(System.out::println);
}

ディレクトリサイズの計算

ディレクトリ以下にあるすべてのファイルサイズを合計します:

try (var stream = Files.walk(Path.of("/home/user/data"))) {
    long totalBytes = stream
        .filter(Files::isRegularFile)
        .mapToLong(p -> {
            try { return Files.size(p); }
            catch (IOException e) { return 0; }
        })
        .sum();
    System.out.printf("Total: %.2f MB%n", totalBytes / 1_048_576.0);
}

Files.list と Files.walk

Files.list(dir) は、単一のディレクトリの直下にある内容だけを列挙します(ls のような動作です)。Files.walk はサブディレクトリも再帰的に処理します。

// Only immediate children:
try (var stream = Files.list(Path.of("/home/user"))) {
    stream.forEach(System.out::println);
}

属性ベースの検索に使う Files.find

Files.find(root, depth, matcher) は、ファイル属性を条件に検索する場合、walk と filter を組み合わせるより効率的です:

import java.nio.file.attribute.BasicFileAttributes;

try (var stream = Files.find(
        Path.of("/home/user"),
        Integer.MAX_VALUE,
        (p, attrs) -> attrs.isRegularFile() && attrs.size() > 1_000_000
)) {
    stream.forEach(p -> System.out.println("Large file: " + p));
}

ディレクトリツリーの削除

walk と sorted(reversed) を使用して、ディレクトリとその内容をすべて削除します(最も深いファイルから先に削除します):

Path toDelete = Path.of("/tmp/workdir");
try (var stream = Files.walk(toDelete)) {
    stream.sorted(Comparator.reverseOrder())
          .forEach(p -> {
              try { Files.delete(p); }
              catch (IOException e) { e.printStackTrace(); }
          });
}

ディレクトリツリーのコピー

ソースツリーを走査し、ディレクトリ構造を維持したまま各ファイルをコピーします:

Path src = Path.of("/source"), dst = Path.of("/destination");
try (var stream = Files.walk(src)) {
    stream.forEach(p -> {
        try {
            Path target = dst.resolve(src.relativize(p));
            if (Files.isDirectory(p)) Files.createDirectories(target);
            else Files.copy(p, target, StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) { throw new RuntimeException(e); }
    });
}

アクセスできないファイルの処理

Files.walk は、読み取れないディレクトリに遭遇すると IOException をスローします。FileVisitOption.FOLLOW_LINKS は慎重に使用してください。シンボリックリンクのループによって無限再帰が発生する可能性があります。

try (var stream = Files.walk(Path.of("/"),
        FileVisitOption.FOLLOW_LINKS)) { // caution: symlink loops
    // ...
} catch (IOException e) {
    System.err.println("Access error: " + e.getMessage());
}

walkFileTree:イベントベースの走査

走査前処理、走査後処理、エラー処理をより細かく制御するには、FileVisitor とともに Files.walkFileTree() を使用します:

Files.walkFileTree(Path.of("/home/user"), new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
        System.out.println("File: " + file);
        return FileVisitResult.CONTINUE;
    }
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        System.out.println("Dir: " + dir);
        return FileVisitResult.CONTINUE;
    }
});

クイックチェック

ディレクトリの直下にある子要素だけを、再帰せずに列挙するには、どの Files メソッドを使用すべきでしょうか?

復習:Files.walk

重要なポイント:

  • Files.walk(root) — すべてのパスを再帰的に返す遅延 Stream
  • ストリームを閉じるため、必ず try-with-resources を使用します
  • Files.isRegularFile/isDirectory でフィルタリングし、endsWith で拡張子によるフィルタリングを行います
  • Files.list(dir) — 直下の子要素だけを返します
  • Files.find — 属性ベースの効率的な検索を行います
  • walkFileTree — 走査前後のコールバックを使用するイベントベースの走査です

よくある質問

「Files.walk によるディレクトリツリーの走査」レッスンは無料ですか?

はい。「Files.walk によるディレクトリツリーの走査」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「Files.walk によるディレクトリツリーの走査」で何を学びますか?

Files.walk でファイルを再帰的に一覧表示し、拡張子で絞り込み、ディレクトリサイズを計算します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「Files.walk によるディレクトリツリーの走査」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Path:ファイル場所の表現
  2. Files ユーティリティ:読み取り、書き込み、コピー、移動
  3. Files.walk によるディレクトリツリーの走査
  4. WatchService:ファイル変更の監視
← Java Academyに戻る