Java : FileVisitor - API使用例
FileVisitor (Java SE 18 & JDK 18) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。
概要
ファイルのビジターです。 このインタフェースの実装は、ファイル・ツリー内の各ファイルをビジットするFiles.walkFileTreeメソッドに渡されます。
FileVisitor インタフェースは、次のようなシーケンスで使われます。
- Files.walkFileTree に、基準となるディレクトリと FileVisitor を渡す。
- 渡したディレクトリを基準に、その下層のファイルやディレクトリに順々にアクセスする。
- アクセス結果は、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 --