その中でも walk() や find() は、とあるディレクトリ配下を一気に収集して Stream として返してくれる、というとっても便利そうなメソッドなのですが、
なんとも悲しい落とし穴があります。
それは途中で Exception が発生した場合にはそこで終了してしまい、エラーハンドリングが出来ないというものです。
例えば、
try(Stream<Path> stp = Files.walk(Paths.get(”c:\\Windows”))){のように c:\\Windows 配下のような権限不可で読めないファイル・ディレクトリの宝庫のところを対象として walk() すると、どこかで java.nio.file.AccessDeniedException とかが起きて walk 処理が止まってしまいます。
stp.forEach(System.out::println); }
そういうところは飛ばして続けるという選択肢がありません。
これは Files.Find() でも同じです。
この点については、このページで議論されているように、FileVisitOption.IGNORE_ON_IOEXCEPTION なんてのが指定できると良いのにと思います。
ともかく、現状、こういう権限不可で読めない状況に対処して処理を続けたい場合には、
Files.walkFileTree() を使い visitFileFailed() でエラーハンドリングをするという対処方法になるようです。
(walk(), find() 相当の収集処理は visitFile() で自力で実装する)
- AccessDeniedException with FileVisitor in Java
http://technojeeves.com/index.php/82-accessdeniedexception-with-filevisitor-in-java
で実装例がありますが、ポイントのところだけ抜き出すと
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.printf("Visiting file %s\n", file);
/* ここで正常ケースの file について、リスト化していくなり、何か処理するなりを実装 */
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException {
System.err.printf("Visiting failed for %s\n", file);
/* アクセス不可なファイルは無視する */
return FileVisitResult.SKIP_SUBTREE;
}
});
といった感じになります。
0 件のコメント:
コメントを投稿