2017-01-15 19 views
4

私はFiles.walkを使用して、最も簡単なコードを持っている:キャッチ例外

Stream<Path> stream = Files.walk(Paths.get("C:\\")); 
stream.forEach(f -> { 
    System.out.println(f); 
}); 

このコードは​​へ

Exception in thread "main" java.io.UncheckedIOException: java.nio.file.AccessDeniedException: C:\Documents and Settings 
    at java.nio.file.FileTreeIterator.fetchNextIfNeeded(Unknown Source) 
    at java.nio.file.FileTreeIterator.hasNext(Unknown Source) 
    at java.util.Iterator.forEachRemaining(Unknown Source) 
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining (Unknown Source) 
    at java.util.stream.AbstractPipeline.copyInto(Unknown Source) 
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown 
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential (Unknown Source) 
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) 
    at java.util.stream.AbstractPipeline.evaluate(Unknown Source) 
    at java.util.stream.ReferencePipeline.forEach(Unknown Source) 
    at devl.test.FindDuplicates.main(FindDuplicates.java:53) 
Caused by: java.nio.file.AccessDeniedException: C:\Documents and Settings 
    at sun.nio.fs.WindowsException.translateToIOException(Unknown Source) 
    at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source) 
    at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source) 
    at sun.nio.fs.WindowsDirectoryStream.<init>(Unknown Source) 
    at sun.nio.fs.WindowsFileSystemProvider.newDirectoryStream (Unknown Source) 
    at java.nio.file.Files.newDirectoryStream(Unknown Source) 
    at java.nio.file.FileTreeWalker.visit(Unknown Source) 
    at java.nio.file.FileTreeWalker.next(Unknown Source) 
    ... 11 more 

そして、スタックトレースポイントをスローします。コードの前にtry/catchを追加すると、例外がスローされたときにファイルの読み込みが停止されます。

問題は次のとおりです。例外がスローされても、ドライブCで異なるファイルを読み込み続けるようにします。

foreach内のtry/catchを追加すると、問題を解決するように見えます - どうすればいいですか(ではなく、System.out.println(f);)。

私が(でもやってstream.filter(f -> false)が失敗した)

Stream<Path> s = stream.filter(f -> !f.toFile().getAbsolutePath().contains("Documents and Setting")); 
s.forEach(f -> { 

をすることによって、これを回避しようとしましたが、同じ例外がスローされますのでご注意ください。

編集:例外(like I was suggested)を再スローしたくないことに注意してください。したがって、s.forEach(LambdaExceptionUtil.rethrowConsumer(System.out::println))を使用しても、正確なスタックトレースは失敗します。

+3

問題はラムダにアクセスするのではなく、歩行自体で発生するため、ラムダでこれを修正することはできません。あなたがこれを正直に修正できるかどうかはわかりません。このAPIでこれを防ぐオプションは実際にはありません。代わりにあなた自身の訪問者を実装する必要があるかもしれません。 –

+1

[Java 8ストリームの中からCHECKED例外をどのように投げることができますか?](http://stackoverflow.com/questions/27644361/how-can-i-throw-checked-exceptions-from-inside-java-8 -streams) – ares

答えて

4

再帰的ディレクトリトラバーサル中にエラーを無視するには、エラー処理を行うFileVisitorを使用してwalkFileTreeを使用する必要があります。

ストリームベースのコンビニエンスラッパー(walk)は、最初にエラーが発生したときに終了するだけで、それを防ぐことはできません。

0

ディレクトリのリストがあなたの後ろにある場合、代わりにDirectoryStreamPathsを使用しないのはなぜですか? https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html

さらに、Java8と組み合わせて使用​​することができますが、例外処理の方がはるかに優れています。

+0

これは私が何をしたのかではない - できるだけ簡単なコードを表示したい – Ran