--- old/src/java.base/share/classes/java/nio/file/FileTreeIterator.java 2015-07-02 15:16:17.613612918 +0200 +++ new/src/java.base/share/classes/java/nio/file/FileTreeIterator.java 2015-07-02 15:16:17.543612465 +0200 @@ -33,6 +33,7 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.nio.file.FileTreeWalker.Event; +import java.util.function.Consumer; /** * An {@code Iterator to iterate over the nodes of a file tree. @@ -49,6 +50,7 @@ */ class FileTreeIterator implements Iterator, Closeable { + private final Consumer ioExceptionHandler; private final FileTreeWalker walker; private Event next; @@ -57,26 +59,38 @@ * * @throws IllegalArgumentException * if {@code maxDepth} is negative - * @throws IOException - * if an I/O errors occurs opening the starting file * @throws SecurityException * if the security manager denies access to the starting file * @throws NullPointerException - * if {@code start} or {@code options} is {@ocde null} or - * the options array contains a {@code null} element + * if {@code start} or {@code options} or {@code ioExceptionHandler} + * is {@code null} or the options array contains a {@code null} element */ - FileTreeIterator(Path start, int maxDepth, FileVisitOption... options) - throws IOException + FileTreeIterator(Path start, int maxDepth, + Consumer ioExceptionHandler, + FileVisitOption... options) { + this.ioExceptionHandler = Objects.requireNonNull(ioExceptionHandler); this.walker = new FileTreeWalker(Arrays.asList(options), maxDepth); this.next = walker.walk(start); assert next.type() == FileTreeWalker.EventType.ENTRY || next.type() == FileTreeWalker.EventType.START_DIRECTORY; - // IOException if there a problem accessing the starting file + // handle IOException if there a problem accessing the starting file IOException ioe = next.ioeException(); - if (ioe != null) - throw ioe; + if (ioe != null) { + next = null; + try { + ioExceptionHandler.accept(ioe); + } catch (Throwable t) { + // clean-up when constructors throws + try { + close(); + } catch (Throwable ct) { + t.addSuppressed(ct); + } + throw t; + } + } } private void fetchNextIfNeeded() { @@ -84,11 +98,11 @@ FileTreeWalker.Event ev = walker.next(); while (ev != null) { IOException ioe = ev.ioeException(); - if (ioe != null) - throw new UncheckedIOException(ioe); - + if (ioe != null) { + ioExceptionHandler.accept(ioe); + } // END_DIRECTORY events are ignored - if (ev.type() != FileTreeWalker.EventType.END_DIRECTORY) { + else if (ev.type() != FileTreeWalker.EventType.END_DIRECTORY) { next = ev; return; }