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.
-
3You 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– Mark Rotteveel2017年01月15日 10:07:00 +00:00Commented Jan 15, 2017 at 10:07
-
1Possible duplicate of How can I throw CHECKED exceptions from inside Java 8 streams?ares– ares2017年01月15日 10:18:34 +00:00Commented Jan 15, 2017 at 10:18
2 Answers 2
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.
Comments
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.