4

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.

Community
  • 1
  • 1
Ran
  • 657
  • 2
  • 13
  • 29
  • 3
    You can't fix this in the lambda, as the problem occurs in the walking itself, not in accessing the lambda. I'm not sure if you can fix this to be honest; I don't really see an option to prevent this in this API; you may need to implement your own visitor instead. – Mark Rotteveel Jan 15 '17 at 10:07
  • 1
    Possible duplicate of [How can I throw CHECKED exceptions from inside Java 8 streams?](http://stackoverflow.com/questions/27644361/how-can-i-throw-checked-exceptions-from-inside-java-8-streams) – ares Jan 15 '17 at 10:18

2 Answers2

4

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.

the8472
  • 40,999
  • 5
  • 70
  • 122
0

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.

akortex
  • 5,067
  • 2
  • 25
  • 57
  • It is not what I am after - I just wanted to show you the simplest code possible... – Ran Jan 15 '17 at 10:22