Java : FileVisitor - API使用例

FileVisitor (Java SE 18 & JDK 18) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。


概要

ファイルのビジターです。 このインタフェースの実装は、ファイル・ツリー内の各ファイルをビジットするFiles.walkFileTreeメソッドに渡されます。

クラス構成

FileVisitor インタフェースは、次のようなシーケンスで使われます。

  1. Files.walkFileTree に、基準となるディレクトリと FileVisitor を渡す。
  2. 渡したディレクトリを基準に、その下層のファイルやディレクトリに順々にアクセスする。
  3. アクセス結果は、FileVisitor のコールバックとして受け取る。

単純な実装として、SimpleFileVisitor があります。

// ファイル・ツリー構成です。

// --- PowerShell ---
//PS R:\java-work> tree /F
//...
//R:.
//└─target-dir
//    ├─dir1
//    │      aaa.txt
//    │      bbb.txt
//    │
//    └─dir2
//            ccc.txt
//            ddd.txt

// 対象のディレクトリと、その中のファイル・ディレクトリを削除する例です。
final FileVisitor<Path> visitor = new SimpleFileVisitor<>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        System.out.println("visitFile          : " + file);

        Files.delete(file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
        System.out.println("postVisitDirectory : " + dir);

        if (exc != null) {
            throw exc;
        }

        Files.delete(dir);
        return FileVisitResult.CONTINUE;
    }
};

final var targetDir = Path.of("R:", "java-work", "target-dir");
System.out.println("target dir : " + targetDir);
System.out.println("exists : " + Files.exists(targetDir));

System.out.println("-- walkFileTree : start --");
Files.walkFileTree(targetDir, visitor);

System.out.println("-- walkFileTree : end --");
System.out.println("exists : " + Files.exists(targetDir));

// 結果
// ↓
//target dir : R:\java-work\target-dir
//exists : true
//-- walkFileTree : start --
//visitFile          : R:\java-work\target-dir\dir1\aaa.txt
//visitFile          : R:\java-work\target-dir\dir1\bbb.txt
//postVisitDirectory : R:\java-work\target-dir\dir1
//visitFile          : R:\java-work\target-dir\dir2\ccc.txt
//visitFile          : R:\java-work\target-dir\dir2\ddd.txt
//postVisitDirectory : R:\java-work\target-dir\dir2
//postVisitDirectory : R:\java-work\target-dir
//-- walkFileTree : end --
//exists : false

関連:ディレクトリを丸ごと削除


メソッド

FileVisitResult postVisitDirectory (T dir, IOException exc)

ディレクトリ内のエントリ、およびそのすべての子孫がビジットされたあとにそのディレクトリに対して呼び出されます。

// --- PowerShell ---
//PS R:\java-work> tree /F
//...
//R:.
//│  aaa.txt
//│  bbb.txt
//│
//├─dir1
//│  │  ccc.txt
//│  │  ddd.txt
//│  │
//│  └─dir1-2
//│          eee.txt
//│          fff.txt
//│
//└─dir2
//        ggg.txt
//        hhh.txt

final var start = Path.of("R:", "java-work");
System.out.println("start dir : " + start);

final var visitor = new FileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        System.out.println("preVisitDirectory  : " + dir);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
        System.out.println("visitFile          : " + file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        System.out.println("visitFileFailed    : " + file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
        System.out.println("postVisitDirectory : " + dir);
        return FileVisitResult.CONTINUE;
    }
};

System.out.println("-- walkFileTree : start --");
Files.walkFileTree(start, visitor);

System.out.println("-- walkFileTree : end --");

// 結果
// ↓
//start dir : R:\java-work
//-- walkFileTree : start --
//preVisitDirectory  : R:\java-work
//visitFile          : R:\java-work\aaa.txt
//visitFile          : R:\java-work\bbb.txt
//preVisitDirectory  : R:\java-work\dir1
//visitFile          : R:\java-work\dir1\ccc.txt
//visitFile          : R:\java-work\dir1\ddd.txt
//preVisitDirectory  : R:\java-work\dir1\dir1-2
//visitFile          : R:\java-work\dir1\dir1-2\eee.txt
//visitFile          : R:\java-work\dir1\dir1-2\fff.txt
//postVisitDirectory : R:\java-work\dir1\dir1-2
//postVisitDirectory : R:\java-work\dir1
//preVisitDirectory  : R:\java-work\dir2
//visitFile          : R:\java-work\dir2\ggg.txt
//visitFile          : R:\java-work\dir2\hhh.txt
//postVisitDirectory : R:\java-work\dir2
//postVisitDirectory : R:\java-work
//-- walkFileTree : end --
final var start = Path.of("R:", "java-work");
System.out.println("start dir : " + start);

final var visitor = new FileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        System.out.println("preVisitDirectory  : " + dir);

        if (Path.of("dir1").equals(dir.getFileName())) {
            System.out.println("                     dir1 SKIP!");
            return FileVisitResult.SKIP_SUBTREE;
        }

        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
        System.out.println("visitFile          : " + file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        System.out.println("visitFileFailed    : " + file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
        System.out.println("postVisitDirectory : " + dir);
        return FileVisitResult.CONTINUE;
    }
};

System.out.println("-- walkFileTree : start --");
Files.walkFileTree(start, visitor);

System.out.println("-- walkFileTree : end --");

// 結果
// ↓
//start dir : R:\java-work
//-- walkFileTree : start --
//preVisitDirectory  : R:\java-work
//visitFile          : R:\java-work\aaa.txt
//visitFile          : R:\java-work\bbb.txt
//preVisitDirectory  : R:\java-work\dir1
//                     dir1 SKIP!
//preVisitDirectory  : R:\java-work\dir2
//visitFile          : R:\java-work\dir2\ggg.txt
//visitFile          : R:\java-work\dir2\hhh.txt
//postVisitDirectory : R:\java-work\dir2
//postVisitDirectory : R:\java-work
//-- walkFileTree : end --

FileVisitResult preVisitDirectory (T dir, BasicFileAttributes attrs)

ディレクトリ内のエントリがビジットされる前に、そのディレクトリに対して呼び出されます。

このメソッドの使用例は、postVisitDirectory(T dir, IOException exc) にまとめて記載しました。
そちらのAPI使用例をご参照ください。

FileVisitResult visitFile (T file, BasicFileAttributes attrs)

ディレクトリ内のファイルに対して呼び出されます。

このメソッドの使用例は、postVisitDirectory(T dir, IOException exc) にまとめて記載しました。
そちらのAPI使用例をご参照ください。

FileVisitResult visitFileFailed (T file, IOException exc)

ビジットできなかったファイルに対して呼び出されます。

// --- PowerShell ---
//PS R:\java-work> tree /F
//...
//R:.
//├─dir1
//└─dir2
//        aaa.txt
//
//PS R:\java-work> ls | Get-Acl
//
//    Directory: R:\java-work
//
//Path Owner           Access
//---- -----           ------
//dir1 MY-PC\test-user BUILTIN\Administrators Deny  ReadData…
//dir2 MY-PC\test-user BUILTIN\Administrators Allow  FullControl…

// ※意図的に失敗ケースを発生させるために、dir1ディレクトリは読み取り権限を外しています。

final var start = Path.of("R:", "java-work");
System.out.println("start dir : " + start);

final var visitor = new FileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        System.out.println("preVisitDirectory  : " + dir);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
        System.out.println("visitFile          : " + file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        System.out.println("visitFileFailed    : " + file);
        System.out.println("IOException        : " + exc);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
        System.out.println("postVisitDirectory : " + dir);
        return FileVisitResult.CONTINUE;
    }
};

System.out.println("-- walkFileTree : start --");
Files.walkFileTree(start, visitor);

System.out.println("-- walkFileTree : end --");

// 結果
// ↓
//start dir : R:\java-work
//-- walkFileTree : start --
//preVisitDirectory  : R:\java-work
//visitFileFailed    : R:\java-work\dir1
//IOException        : java.nio.file.AccessDeniedException: R:\java-work\dir1
//preVisitDirectory  : R:\java-work\dir2
//visitFile          : R:\java-work\dir2\aaa.txt
//postVisitDirectory : R:\java-work\dir2
//postVisitDirectory : R:\java-work
//-- walkFileTree : end --

関連記事

ページの先頭へ