広告

Java : SimpleFileVisitor - API使用例

SimpleFileVisitor (Java SE 22 & JDK 22) の使い方まとめです。
ほとんどのメソッドにサンプルコードがあります。
APIドキュメントのおともにどうぞ。


概要

すべてのファイルをビジットして入出力エラーを再度スローするというデフォルトの動作を持つ、簡単なファイル・ビジターです。

クラス構成

SimpleFileVisitor は、FileVisitor インタフェースのシンプルな実装です。

FileVisitor インタフェースを直接実装すると、不要なメソッドもとりあえずオーバーライドしなければなりません。
そんなときは、SimpleFileVisitor を使うと不要なメソッドのオーバーライドを省略できて便利です。

// ファイル構成です。

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

// 対象のディレクトリと、その中のファイル・ディレクトリを削除する例です。
final var visitor = new SimpleFileVisitor<Path>() {
    @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

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


コンストラクタ

SimpleFileVisitor ()

このクラスの新しいインスタンスを初期化します。

// --- 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 SimpleFileVisitor<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 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 SimpleFileVisitor<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 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 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 SimpleFileVisitor<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 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 SimpleFileVisitor<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 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)

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

// --- 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 SimpleFileVisitor<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 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 SimpleFileVisitor<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 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 visitFile (T file, BasicFileAttributes attrs)

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

// --- 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 SimpleFileVisitor<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 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 SimpleFileVisitor<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 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 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 SimpleFileVisitor<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;
    }
};

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
//-- walkFileTree : end --

関連記事

ページの先頭へ