< prev index next >

src/java.base/share/classes/java/nio/file/FileTreeIterator.java

Print this page

        

@@ -31,10 +31,11 @@
 import java.util.Arrays;
 import java.util.Iterator;
 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.
  *
  * <pre>{@code

@@ -47,50 +48,63 @@
  *     }
  * }</pre>
  */
 
 class FileTreeIterator implements Iterator<Event>, Closeable {
+    private final Consumer<IOException> ioExceptionHandler;
     private final FileTreeWalker walker;
     private Event next;
 
     /**
      * Creates a new iterator to walk the file tree starting at the given file.
      *
      * @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<IOException> 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() {
         if (next == null) {
             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;
                 }
                 ev = walker.next();
             }
< prev index next >