Ran
Ran

Reputation: 662

Catching Exceptions in lambda expressions

I have the simplest code using Files.walk:

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

This code throws

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

And the stacktrace points to stream.forEach(f -> {. Adding a try/catch before the code makes it to stop reading the files when the exception is thrown.

The thing is - I want the code to continue reading different files on drive C even though the exception is thrown.

It seems like somehow adding a try/catch inside the foreach would solve it - how do I do it (a try/catch on f -> {, not the System.out.println(f);)?

Please note that I tried to circumvent this by doing

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

But the same exception is thrown (even doing stream.filter(f -> false) fails).

EDIT: Please note that I don't want to re-throw an exception (like I was suggested). So using s.forEach(LambdaExceptionUtil.rethrowConsumer(System.out::println)) still fails with the exact stacktrace.

Upvotes: 4

Views: 1081

Answers (2)

the8472
the8472

Reputation: 43042

To ignore errors during recursive directory traversal you need to use walkFileTree with a FileVisitor that does error handling.

The stream based convenience wrappers (walk) simply terminate on the first error they encounter, you can't prevent that.

Upvotes: 4

akourt
akourt

Reputation: 5563

If the listing of directories is what you're after, then why not use DirectoryStreamPaths instead? See the doc here for more: https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html

Furthere you can use it in conjuction with Java8 and what's more the exception handling is quite good.

Upvotes: 0

Related Questions