src/share/classes/java/nio/file/Files.java

Print this page
rev 7982 : 8017513: Support for closeable streams
8022237: j.u.s.BaseStream.onClose() has an issue in implementation or requires spec clarification
8022572: Same exception instances thrown from j.u.stream.Stream.onClose() handlers are not listed as suppressed
Summary: BaseStream implements AutoCloseable; Remove CloseableStream and DelegatingStream
Reviewed-by: alanb, mduigou, psandoz
Contributed-by: brian.goetz@oracle.com


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.nio.file;
  27 
  28 import java.nio.file.attribute.*;
  29 import java.nio.file.spi.FileSystemProvider;
  30 import java.nio.file.spi.FileTypeDetector;
  31 import java.nio.channels.Channels;
  32 import java.nio.channels.FileChannel;
  33 import java.nio.channels.SeekableByteChannel;
  34 import java.io.Closeable;
  35 import java.io.InputStream;
  36 import java.io.OutputStream;
  37 import java.io.Reader;
  38 import java.io.Writer;
  39 import java.io.BufferedReader;
  40 import java.io.BufferedWriter;




  41 import java.io.InputStreamReader;

  42 import java.io.OutputStreamWriter;
  43 import java.io.IOException;
  44 import java.io.UncheckedIOException;
  45 import java.util.*;
  46 import java.util.function.BiPredicate;
  47 import java.util.stream.CloseableStream;
  48 import java.util.stream.DelegatingStream;
  49 import java.util.stream.Stream;
  50 import java.util.stream.StreamSupport;
  51 import java.security.AccessController;
  52 import java.security.PrivilegedAction;
  53 import java.nio.charset.Charset;
  54 import java.nio.charset.CharsetDecoder;
  55 import java.nio.charset.CharsetEncoder;
































  56 
  57 /**
  58  * This class consists exclusively of static methods that operate on files,
  59  * directories, or other types of files.
  60  *
  61  * <p> In most cases, the methods defined here will delegate to the associated
  62  * file system provider to perform the file operations.
  63  *
  64  * @since 1.7
  65  */
  66 
  67 public final class Files {
  68     private Files() { }
  69 
  70     /**
  71      * Returns the {@code FileSystemProvider} to delegate to.
  72      */
  73     private static FileSystemProvider provider(Path path) {
  74         return path.getFileSystem().provider();
  75     }
  76 















  77     // -- File contents --
  78 
  79     /**
  80      * Opens a file, returning an input stream to read from the file. The stream
  81      * will not be buffered, and is not required to support the {@link
  82      * InputStream#mark mark} or {@link InputStream#reset reset} methods. The
  83      * stream will be safe for access by multiple concurrent threads. Reading
  84      * commences at the beginning of the file. Whether the returned stream is
  85      * <i>asynchronously closeable</i> and/or <i>interruptible</i> is highly
  86      * file system provider specific and therefore not specified.
  87      *
  88      * <p> The {@code options} parameter determines how the file is opened.
  89      * If no options are present then it is equivalent to opening the file with
  90      * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
  91      * READ} option, an implementation may also support additional implementation
  92      * specific options.
  93      *
  94      * @param   path
  95      *          the path to the file to open
  96      * @param   options


3211     public static Path write(Path path, Iterable<? extends CharSequence> lines,
3212                              Charset cs, OpenOption... options)
3213         throws IOException
3214     {
3215         // ensure lines is not null before opening file
3216         Objects.requireNonNull(lines);
3217         CharsetEncoder encoder = cs.newEncoder();
3218         OutputStream out = newOutputStream(path, options);
3219         try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
3220             for (CharSequence line: lines) {
3221                 writer.append(line);
3222                 writer.newLine();
3223             }
3224         }
3225         return path;
3226     }
3227 
3228     // -- Stream APIs --
3229 
3230     /**
3231      * Implementation of CloseableStream
3232      */
3233     private static class DelegatingCloseableStream<T> extends DelegatingStream<T>
3234         implements CloseableStream<T>
3235     {
3236         private final Closeable closeable;
3237 
3238         DelegatingCloseableStream(Closeable c, Stream<T> delegate) {
3239             super(delegate);
3240             this.closeable = c;
3241         }
3242 
3243         public void close() {
3244             try {
3245                 closeable.close();
3246             } catch (IOException ex) {
3247                 throw new UncheckedIOException(ex);
3248             }
3249         }
3250     }
3251 
3252     /**
3253      * Return a lazily populated {@code CloseableStream}, the elements of
3254      * which are the entries in the directory.  The listing is not recursive.
3255      *
3256      * <p> The elements of the stream are {@link Path} objects that are
3257      * obtained as if by {@link Path#resolve(Path) resolving} the name of the
3258      * directory entry against {@code dir}. Some file systems maintain special
3259      * links to the directory itself and the directory's parent directory.
3260      * Entries representing these links are not included.
3261      *
3262      * <p> The stream is <i>weakly consistent</i>. It is thread safe but does
3263      * not freeze the directory while iterating, so it may (or may not)
3264      * reflect updates to the directory that occur after returning from this
3265      * method.
3266      *
3267      * <p> When not using the try-with-resources construct, then the stream's
3268      * {@link CloseableStream#close close} method should be invoked after the
3269      * operation is completed so as to free any resources held for the open
3270      * directory. Operating on a closed stream behaves as if the end of stream



3271      * has been reached. Due to read-ahead, one or more elements may be
3272      * returned after the stream has been closed.
3273      *
3274      * <p> If an {@link IOException} is thrown when accessing the directory
3275      * after this method has returned, it is wrapped in an {@link
3276      * UncheckedIOException} which will be thrown from the method that caused
3277      * the access to take place.
3278      *
3279      * @param   dir  The path to the directory
3280      *
3281      * @return  The {@code CloseableStream} describing the content of the
3282      *          directory
3283      *
3284      * @throws  NotDirectoryException
3285      *          if the file could not otherwise be opened because it is not
3286      *          a directory <i>(optional specific exception)</i>
3287      * @throws  IOException
3288      *          if an I/O error occurs when opening the directory
3289      * @throws  SecurityException
3290      *          In the case of the default provider, and a security manager is
3291      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
3292      *          method is invoked to check read access to the directory.
3293      *
3294      * @see     #newDirectoryStream(Path)
3295      * @since   1.8
3296      */
3297     public static CloseableStream<Path> list(Path dir) throws IOException {
3298         DirectoryStream<Path> ds = Files.newDirectoryStream(dir);

3299         final Iterator<Path> delegate = ds.iterator();
3300 
3301         // Re-wrap DirectoryIteratorException to UncheckedIOException
3302         Iterator<Path> it = new Iterator<Path>() {

3303             public boolean hasNext() {
3304                 try {
3305                     return delegate.hasNext();
3306                 } catch (DirectoryIteratorException e) {
3307                     throw new UncheckedIOException(e.getCause());
3308                 }
3309             }

3310             public Path next() {
3311                 try {
3312                     return delegate.next();
3313                 } catch (DirectoryIteratorException e) {
3314                     throw new UncheckedIOException(e.getCause());
3315                 }
3316             }
3317         };
3318 
3319         Stream<Path> s = StreamSupport.stream(
3320                 Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT),
3321                 false);
3322         return new DelegatingCloseableStream<>(ds, s);





3323     }



3324 
3325     /**
3326      * Return a {@code CloseableStream} that is lazily populated with {@code
3327      * Path} by walking the file tree rooted at a given starting file.  The
3328      * file tree is traversed <em>depth-first</em>, the elements in the stream
3329      * are {@link Path} objects that are obtained as if by {@link
3330      * Path#resolve(Path) resolving} the relative path against {@code start}.
3331      *
3332      * <p> The {@code stream} walks the file tree as elements are consumed.
3333      * The {@code CloseableStream} returned is guaranteed to have at least one
3334      * element, the starting file itself. For each file visited, the stream
3335      * attempts to read its {@link BasicFileAttributes}. If the file is a
3336      * directory and can be opened successfully, entries in the directory, and
3337      * their <em>descendants</em> will follow the directory in the stream as
3338      * they are encountered. When all entries have been visited, then the
3339      * directory is closed. The file tree walk then continues at the next
3340      * <em>sibling</em> of the directory.
3341      *
3342      * <p> The stream is <i>weakly consistent</i>. It does not freeze the
3343      * file tree while iterating, so it may (or may not) reflect updates to
3344      * the file tree that occur after returned from this method.
3345      *
3346      * <p> By default, symbolic links are not automatically followed by this
3347      * method. If the {@code options} parameter contains the {@link
3348      * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
3349      * followed. When following links, and the attributes of the target cannot
3350      * be read, then this method attempts to get the {@code BasicFileAttributes}
3351      * of the link.
3352      *
3353      * <p> If the {@code options} parameter contains the {@link
3354      * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then the stream keeps
3355      * track of directories visited so that cycles can be detected. A cycle
3356      * arises when there is an entry in a directory that is an ancestor of the
3357      * directory. Cycle detection is done by recording the {@link
3358      * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
3359      * or if file keys are not available, by invoking the {@link #isSameFile
3360      * isSameFile} method to test if a directory is the same file as an
3361      * ancestor. When a cycle is detected it is treated as an I/O error with
3362      * an instance of {@link FileSystemLoopException}.
3363      *
3364      * <p> The {@code maxDepth} parameter is the maximum number of levels of
3365      * directories to visit. A value of {@code 0} means that only the starting
3366      * file is visited, unless denied by the security manager. A value of
3367      * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
3368      * levels should be visited.
3369      *
3370      * <p> When a security manager is installed and it denies access to a file
3371      * (or directory), then it is ignored and not included in the stream.
3372      *
3373      * <p> When not using the try-with-resources construct, then the stream's
3374      * {@link CloseableStream#close close} method should be invoked after the
3375      * operation is completed so as to free any resources held for the open
3376      * directory. Operate the stream after it is closed will throw an

3377      * {@link java.lang.IllegalStateException}.
3378      *
3379      * <p> If an {@link IOException} is thrown when accessing the directory
3380      * after this method has returned, it is wrapped in an {@link
3381      * UncheckedIOException} which will be thrown from the method that caused
3382      * the access to take place.
3383      *
3384      * @param   start
3385      *          the starting file
3386      * @param   maxDepth
3387      *          the maximum number of directory levels to visit
3388      * @param   options
3389      *          options to configure the traversal
3390      *
3391      * @return  the {@link CloseableStream} of {@link Path}
3392      *
3393      * @throws  IllegalArgumentException
3394      *          if the {@code maxDepth} parameter is negative
3395      * @throws  SecurityException
3396      *          If the security manager denies access to the starting file.
3397      *          In the case of the default provider, the {@link
3398      *          SecurityManager#checkRead(String) checkRead} method is invoked
3399      *          to check read access to the directory.
3400      * @throws  IOException
3401      *          if an I/O error is thrown when accessing the starting file.
3402      * @since   1.8
3403      */
3404     public static CloseableStream<Path> walk(Path start, int maxDepth,
3405                                              FileVisitOption... options)
3406         throws IOException
3407     {
3408         FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
3409 
3410         Stream<Path> s = StreamSupport.stream(
3411                 Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT),
3412                 false).
3413                 map(entry -> entry.file());
3414         return new DelegatingCloseableStream<>(iterator, s);

3415     }

3416 
3417     /**
3418      * Return a {@code CloseableStream} that is lazily populated with {@code
3419      * Path} by walking the file tree rooted at a given starting file.  The
3420      * file tree is traversed <em>depth-first</em>, the elements in the stream
3421      * are {@link Path} objects that are obtained as if by {@link
3422      * Path#resolve(Path) resolving} the relative path against {@code start}.
3423      *
3424      * <p> This method works as if invoking it were equivalent to evaluating the
3425      * expression:
3426      * <blockquote><pre>
3427      * walk(start, Integer.MAX_VALUE, options)
3428      * </pre></blockquote>
3429      * In other words, it visits all levels of the file tree.
3430      *







3431      * @param   start
3432      *          the starting file
3433      * @param   options
3434      *          options to configure the traversal
3435      *
3436      * @return  the {@link CloseableStream} of {@link Path}
3437      *
3438      * @throws  SecurityException
3439      *          If the security manager denies access to the starting file.
3440      *          In the case of the default provider, the {@link
3441      *          SecurityManager#checkRead(String) checkRead} method is invoked
3442      *          to check read access to the directory.
3443      * @throws  IOException
3444      *          if an I/O error is thrown when accessing the starting file.
3445      *
3446      * @see     #walk(Path, int, FileVisitOption...)
3447      * @since   1.8
3448      */
3449     public static CloseableStream<Path> walk(Path start,
3450                                              FileVisitOption... options)
3451         throws IOException
3452     {
3453         return walk(start, Integer.MAX_VALUE, options);
3454     }
3455 
3456     /**
3457      * Return a {@code CloseableStream} that is lazily populated with {@code
3458      * Path} by searching for files in a file tree rooted at a given starting
3459      * file.
3460      *
3461      * <p> This method walks the file tree in exactly the manner specified by
3462      * the {@link #walk walk} method. For each file encountered, the given
3463      * {@link BiPredicate} is invoked with its {@link Path} and {@link
3464      * BasicFileAttributes}. The {@code Path} object is obtained as if by
3465      * {@link Path#resolve(Path) resolving} the relative path against {@code
3466      * start} and is only included in the returned {@link CloseableStream} if
3467      * the {@code BiPredicate} returns true. Compare to calling {@link
3468      * java.util.stream.Stream#filter filter} on the {@code Stream}
3469      * returned by {@code walk} method, this method may be more efficient by
3470      * avoiding redundant retrieval of the {@code BasicFileAttributes}.
3471      *







3472      * <p> If an {@link IOException} is thrown when accessing the directory
3473      * after returned from this method, it is wrapped in an {@link
3474      * UncheckedIOException} which will be thrown from the method that caused
3475      * the access to take place.
3476      *
3477      * @param   start
3478      *          the starting file
3479      * @param   maxDepth
3480      *          the maximum number of directory levels to search
3481      * @param   matcher
3482      *          the function used to decide whether a file should be included
3483      *          in the returned stream
3484      * @param   options
3485      *          options to configure the traversal
3486      *
3487      * @return  the {@link CloseableStream} of {@link Path}
3488      *
3489      * @throws  IllegalArgumentException
3490      *          if the {@code maxDepth} parameter is negative
3491      * @throws  SecurityException
3492      *          If the security manager denies access to the starting file.
3493      *          In the case of the default provider, the {@link
3494      *          SecurityManager#checkRead(String) checkRead} method is invoked
3495      *          to check read access to the directory.
3496      * @throws  IOException
3497      *          if an I/O error is thrown when accessing the starting file.
3498      *
3499      * @see     #walk(Path, int, FileVisitOption...)
3500      * @since   1.8
3501      */
3502     public static CloseableStream<Path> find(Path start,
3503                                              int maxDepth,
3504                                              BiPredicate<Path, BasicFileAttributes> matcher,
3505                                              FileVisitOption... options)
3506         throws IOException
3507     {
3508         FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
3509 
3510         Stream<Path> s = StreamSupport.stream(
3511                 Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT),
3512                 false).
3513                 filter(entry -> matcher.test(entry.file(), entry.attributes())).
3514                 map(entry -> entry.file());
3515         return new DelegatingCloseableStream<>(iterator, s);

3516     }

3517 
3518     /**
3519      * Read all lines from a file as a {@code CloseableStream}.  Unlike {@link
3520      * #readAllLines(Path, Charset) readAllLines}, this method does not read
3521      * all lines into a {@code List}, but instead populates lazily as the stream
3522      * is consumed.
3523      *
3524      * <p> Bytes from the file are decoded into characters using the specified
3525      * charset and the same line terminators as specified by {@code
3526      * readAllLines} are supported.
3527      *
3528      * <p> After this method returns, then any subsequent I/O exception that
3529      * occurs while reading from the file or when a malformed or unmappable byte
3530      * sequence is read, is wrapped in an {@link UncheckedIOException} that will
3531      * be thrown form the
3532      * {@link java.util.stream.Stream} method that caused the read to take
3533      * place. In case an {@code IOException} is thrown when closing the file,
3534      * it is also wrapped as an {@code UncheckedIOException}.
3535      *
3536      * <p> When not using the try-with-resources construct, then stream's
3537      * {@link CloseableStream#close close} method should be invoked after
3538      * operation is completed so as to free any resources held for the open
3539      * file.

3540      *

3541      * @param   path
3542      *          the path to the file
3543      * @param   cs
3544      *          the charset to use for decoding
3545      *
3546      * @return  the lines from the file as a {@code CloseableStream}
3547      *
3548      * @throws  IOException
3549      *          if an I/O error occurs opening the file
3550      * @throws  SecurityException
3551      *          In the case of the default provider, and a security manager is
3552      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
3553      *          method is invoked to check read access to the file.
3554      *
3555      * @see     #readAllLines(Path, Charset)
3556      * @see     #newBufferedReader(Path, Charset)
3557      * @see     java.io.BufferedReader#lines()
3558      * @since   1.8
3559      */
3560     public static CloseableStream<String> lines(Path path, Charset cs)
3561         throws IOException
3562     {
3563         BufferedReader br = Files.newBufferedReader(path, cs);
3564         return new DelegatingCloseableStream<>(br, br.lines());








3565     }



3566 }


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.nio.file;
  27 











  28 import java.io.BufferedReader;
  29 import java.io.BufferedWriter;
  30 import java.io.Closeable;
  31 import java.io.File;
  32 import java.io.IOException;
  33 import java.io.InputStream;
  34 import java.io.InputStreamReader;
  35 import java.io.OutputStream;
  36 import java.io.OutputStreamWriter;
  37 import java.io.Reader;
  38 import java.io.UncheckedIOException;
  39 import java.io.Writer;
  40 import java.nio.channels.Channels;
  41 import java.nio.channels.FileChannel;
  42 import java.nio.channels.SeekableByteChannel;




  43 import java.nio.charset.Charset;
  44 import java.nio.charset.CharsetDecoder;
  45 import java.nio.charset.CharsetEncoder;
  46 import java.nio.file.attribute.BasicFileAttributeView;
  47 import java.nio.file.attribute.BasicFileAttributes;
  48 import java.nio.file.attribute.DosFileAttributes;
  49 import java.nio.file.attribute.FileAttribute;
  50 import java.nio.file.attribute.FileAttributeView;
  51 import java.nio.file.attribute.FileOwnerAttributeView;
  52 import java.nio.file.attribute.FileStoreAttributeView;
  53 import java.nio.file.attribute.FileTime;
  54 import java.nio.file.attribute.PosixFileAttributeView;
  55 import java.nio.file.attribute.PosixFileAttributes;
  56 import java.nio.file.attribute.PosixFilePermission;
  57 import java.nio.file.attribute.UserPrincipal;
  58 import java.nio.file.spi.FileSystemProvider;
  59 import java.nio.file.spi.FileTypeDetector;
  60 import java.security.AccessController;
  61 import java.security.PrivilegedAction;
  62 import java.util.ArrayList;
  63 import java.util.Arrays;
  64 import java.util.Collections;
  65 import java.util.EnumSet;
  66 import java.util.HashSet;
  67 import java.util.Iterator;
  68 import java.util.List;
  69 import java.util.Map;
  70 import java.util.Objects;
  71 import java.util.ServiceLoader;
  72 import java.util.Set;
  73 import java.util.Spliterator;
  74 import java.util.Spliterators;
  75 import java.util.function.BiPredicate;
  76 import java.util.stream.Stream;
  77 import java.util.stream.StreamSupport;
  78 
  79 /**
  80  * This class consists exclusively of static methods that operate on files,
  81  * directories, or other types of files.
  82  *
  83  * <p> In most cases, the methods defined here will delegate to the associated
  84  * file system provider to perform the file operations.
  85  *
  86  * @since 1.7
  87  */
  88 
  89 public final class Files {
  90     private Files() { }
  91 
  92     /**
  93      * Returns the {@code FileSystemProvider} to delegate to.
  94      */
  95     private static FileSystemProvider provider(Path path) {
  96         return path.getFileSystem().provider();
  97     }
  98 
  99     /**
 100      * Convert a Closeable to a Runnable by converting checked IOException
 101      * to UncheckedIOException
 102      */
 103     private static Runnable asUncheckedRunnable(Closeable c) {
 104         return () -> {
 105             try {
 106                 c.close();
 107             }
 108             catch (IOException e) {
 109                 throw new UncheckedIOException(e);
 110             }
 111         };
 112     }
 113 
 114     // -- File contents --
 115 
 116     /**
 117      * Opens a file, returning an input stream to read from the file. The stream
 118      * will not be buffered, and is not required to support the {@link
 119      * InputStream#mark mark} or {@link InputStream#reset reset} methods. The
 120      * stream will be safe for access by multiple concurrent threads. Reading
 121      * commences at the beginning of the file. Whether the returned stream is
 122      * <i>asynchronously closeable</i> and/or <i>interruptible</i> is highly
 123      * file system provider specific and therefore not specified.
 124      *
 125      * <p> The {@code options} parameter determines how the file is opened.
 126      * If no options are present then it is equivalent to opening the file with
 127      * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
 128      * READ} option, an implementation may also support additional implementation
 129      * specific options.
 130      *
 131      * @param   path
 132      *          the path to the file to open
 133      * @param   options


3248     public static Path write(Path path, Iterable<? extends CharSequence> lines,
3249                              Charset cs, OpenOption... options)
3250         throws IOException
3251     {
3252         // ensure lines is not null before opening file
3253         Objects.requireNonNull(lines);
3254         CharsetEncoder encoder = cs.newEncoder();
3255         OutputStream out = newOutputStream(path, options);
3256         try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
3257             for (CharSequence line: lines) {
3258                 writer.append(line);
3259                 writer.newLine();
3260             }
3261         }
3262         return path;
3263     }
3264 
3265     // -- Stream APIs --
3266 
3267     /**
3268      * Return a lazily populated {@code Stream}, the elements of






















3269      * which are the entries in the directory.  The listing is not recursive.
3270      *
3271      * <p> The elements of the stream are {@link Path} objects that are
3272      * obtained as if by {@link Path#resolve(Path) resolving} the name of the
3273      * directory entry against {@code dir}. Some file systems maintain special
3274      * links to the directory itself and the directory's parent directory.
3275      * Entries representing these links are not included.
3276      *
3277      * <p> The stream is <i>weakly consistent</i>. It is thread safe but does
3278      * not freeze the directory while iterating, so it may (or may not)
3279      * reflect updates to the directory that occur after returning from this
3280      * method.
3281      *
3282      * <p> The returned stream encapsulates a {@link DirectoryStream}.
3283      * If timely disposal of file system resources is required, the
3284      * {@code try}-with-resources construct should be used to ensure that the
3285      * stream's {@link Stream#close close} method is invoked after the stream
3286      * operations are completed.
3287      *
3288      * <p> Operating on a closed stream behaves as if the end of stream
3289      * has been reached. Due to read-ahead, one or more elements may be
3290      * returned after the stream has been closed.
3291      *
3292      * <p> If an {@link IOException} is thrown when accessing the directory
3293      * after this method has returned, it is wrapped in an {@link
3294      * UncheckedIOException} which will be thrown from the method that caused
3295      * the access to take place.
3296      *
3297      * @param   dir  The path to the directory
3298      *
3299      * @return  The {@code Stream} describing the content of the
3300      *          directory
3301      *
3302      * @throws  NotDirectoryException
3303      *          if the file could not otherwise be opened because it is not
3304      *          a directory <i>(optional specific exception)</i>
3305      * @throws  IOException
3306      *          if an I/O error occurs when opening the directory
3307      * @throws  SecurityException
3308      *          In the case of the default provider, and a security manager is
3309      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
3310      *          method is invoked to check read access to the directory.
3311      *
3312      * @see     #newDirectoryStream(Path)
3313      * @since   1.8
3314      */
3315     public static Stream<Path> list(Path dir) throws IOException {
3316         DirectoryStream<Path> ds = Files.newDirectoryStream(dir);
3317         try {
3318             final Iterator<Path> delegate = ds.iterator();
3319 
3320             // Re-wrap DirectoryIteratorException to UncheckedIOException
3321             Iterator<Path> it = new Iterator<Path>() {
3322                 @Override
3323                 public boolean hasNext() {
3324                     try {
3325                         return delegate.hasNext();
3326                     } catch (DirectoryIteratorException e) {
3327                         throw new UncheckedIOException(e.getCause());
3328                     }
3329                 }
3330                 @Override
3331                 public Path next() {
3332                     try {
3333                         return delegate.next();
3334                     } catch (DirectoryIteratorException e) {
3335                         throw new UncheckedIOException(e.getCause());
3336                     }
3337                 }
3338             };
3339 
3340             return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false)
3341                                 .onClose(asUncheckedRunnable(ds));
3342         } catch (Error|RuntimeException e) {
3343             try {
3344                 ds.close();
3345             } catch (IOException ex) {
3346                 try {
3347                     e.addSuppressed(ex);
3348                 } catch (Throwable ignore) {}
3349             }
3350             throw e;
3351         }
3352     }
3353 
3354     /**
3355      * Return a {@code Stream} that is lazily populated with {@code
3356      * Path} by walking the file tree rooted at a given starting file.  The
3357      * file tree is traversed <em>depth-first</em>, the elements in the stream
3358      * are {@link Path} objects that are obtained as if by {@link
3359      * Path#resolve(Path) resolving} the relative path against {@code start}.
3360      *
3361      * <p> The {@code stream} walks the file tree as elements are consumed.
3362      * The {@code Stream} returned is guaranteed to have at least one
3363      * element, the starting file itself. For each file visited, the stream
3364      * attempts to read its {@link BasicFileAttributes}. If the file is a
3365      * directory and can be opened successfully, entries in the directory, and
3366      * their <em>descendants</em> will follow the directory in the stream as
3367      * they are encountered. When all entries have been visited, then the
3368      * directory is closed. The file tree walk then continues at the next
3369      * <em>sibling</em> of the directory.
3370      *
3371      * <p> The stream is <i>weakly consistent</i>. It does not freeze the
3372      * file tree while iterating, so it may (or may not) reflect updates to
3373      * the file tree that occur after returned from this method.
3374      *
3375      * <p> By default, symbolic links are not automatically followed by this
3376      * method. If the {@code options} parameter contains the {@link
3377      * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
3378      * followed. When following links, and the attributes of the target cannot
3379      * be read, then this method attempts to get the {@code BasicFileAttributes}
3380      * of the link.
3381      *
3382      * <p> If the {@code options} parameter contains the {@link
3383      * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then the stream keeps
3384      * track of directories visited so that cycles can be detected. A cycle
3385      * arises when there is an entry in a directory that is an ancestor of the
3386      * directory. Cycle detection is done by recording the {@link
3387      * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
3388      * or if file keys are not available, by invoking the {@link #isSameFile
3389      * isSameFile} method to test if a directory is the same file as an
3390      * ancestor. When a cycle is detected it is treated as an I/O error with
3391      * an instance of {@link FileSystemLoopException}.
3392      *
3393      * <p> The {@code maxDepth} parameter is the maximum number of levels of
3394      * directories to visit. A value of {@code 0} means that only the starting
3395      * file is visited, unless denied by the security manager. A value of
3396      * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
3397      * levels should be visited.
3398      *
3399      * <p> When a security manager is installed and it denies access to a file
3400      * (or directory), then it is ignored and not included in the stream.
3401      *
3402      * <p> The returned stream encapsulates one or more {@link DirectoryStream}s.
3403      * If timely disposal of file system resources is required, the
3404      * {@code try}-with-resources construct should be used to ensure that the
3405      * stream's {@link Stream#close close} method is invoked after the stream
3406      * operations are completed.  Operating on a closed stream will result in an
3407      * {@link java.lang.IllegalStateException}.
3408      *
3409      * <p> If an {@link IOException} is thrown when accessing the directory
3410      * after this method has returned, it is wrapped in an {@link
3411      * UncheckedIOException} which will be thrown from the method that caused
3412      * the access to take place.
3413      *
3414      * @param   start
3415      *          the starting file
3416      * @param   maxDepth
3417      *          the maximum number of directory levels to visit
3418      * @param   options
3419      *          options to configure the traversal
3420      *
3421      * @return  the {@link Stream} of {@link Path}
3422      *
3423      * @throws  IllegalArgumentException
3424      *          if the {@code maxDepth} parameter is negative
3425      * @throws  SecurityException
3426      *          If the security manager denies access to the starting file.
3427      *          In the case of the default provider, the {@link
3428      *          SecurityManager#checkRead(String) checkRead} method is invoked
3429      *          to check read access to the directory.
3430      * @throws  IOException
3431      *          if an I/O error is thrown when accessing the starting file.
3432      * @since   1.8
3433      */
3434     public static Stream<Path> walk(Path start, int maxDepth,
3435                                     FileVisitOption... options)
3436             throws IOException {

3437         FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
3438         try {
3439             return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
3440                                 .onClose(iterator::close)
3441                                 .map(entry -> entry.file());
3442         } catch (Error|RuntimeException e) {
3443             iterator.close();
3444             throw e;
3445         }
3446     }
3447 
3448     /**
3449      * Return a {@code Stream} that is lazily populated with {@code
3450      * Path} by walking the file tree rooted at a given starting file.  The
3451      * file tree is traversed <em>depth-first</em>, the elements in the stream
3452      * are {@link Path} objects that are obtained as if by {@link
3453      * Path#resolve(Path) resolving} the relative path against {@code start}.
3454      *
3455      * <p> This method works as if invoking it were equivalent to evaluating the
3456      * expression:
3457      * <blockquote><pre>
3458      * walk(start, Integer.MAX_VALUE, options)
3459      * </pre></blockquote>
3460      * In other words, it visits all levels of the file tree.
3461      *
3462      * <p> The returned stream encapsulates one or more {@link DirectoryStream}s.
3463      * If timely disposal of file system resources is required, the
3464      * {@code try}-with-resources construct should be used to ensure that the
3465      * stream's {@link Stream#close close} method is invoked after the stream
3466      * operations are completed.  Operating on a closed stream will result in an
3467      * {@link java.lang.IllegalStateException}.
3468      *
3469      * @param   start
3470      *          the starting file
3471      * @param   options
3472      *          options to configure the traversal
3473      *
3474      * @return  the {@link Stream} of {@link Path}
3475      *
3476      * @throws  SecurityException
3477      *          If the security manager denies access to the starting file.
3478      *          In the case of the default provider, the {@link
3479      *          SecurityManager#checkRead(String) checkRead} method is invoked
3480      *          to check read access to the directory.
3481      * @throws  IOException
3482      *          if an I/O error is thrown when accessing the starting file.
3483      *
3484      * @see     #walk(Path, int, FileVisitOption...)
3485      * @since   1.8
3486      */
3487     public static Stream<Path> walk(Path start,
3488                                     FileVisitOption... options)
3489             throws IOException {

3490         return walk(start, Integer.MAX_VALUE, options);
3491     }
3492 
3493     /**
3494      * Return a {@code Stream} that is lazily populated with {@code
3495      * Path} by searching for files in a file tree rooted at a given starting
3496      * file.
3497      *
3498      * <p> This method walks the file tree in exactly the manner specified by
3499      * the {@link #walk walk} method. For each file encountered, the given
3500      * {@link BiPredicate} is invoked with its {@link Path} and {@link
3501      * BasicFileAttributes}. The {@code Path} object is obtained as if by
3502      * {@link Path#resolve(Path) resolving} the relative path against {@code
3503      * start} and is only included in the returned {@link Stream} if
3504      * the {@code BiPredicate} returns true. Compare to calling {@link
3505      * java.util.stream.Stream#filter filter} on the {@code Stream}
3506      * returned by {@code walk} method, this method may be more efficient by
3507      * avoiding redundant retrieval of the {@code BasicFileAttributes}.
3508      *
3509      * <p> The returned stream encapsulates one or more {@link DirectoryStream}s.
3510      * If timely disposal of file system resources is required, the
3511      * {@code try}-with-resources construct should be used to ensure that the
3512      * stream's {@link Stream#close close} method is invoked after the stream
3513      * operations are completed.  Operating on a closed stream will result in an
3514      * {@link java.lang.IllegalStateException}.
3515      *
3516      * <p> If an {@link IOException} is thrown when accessing the directory
3517      * after returned from this method, it is wrapped in an {@link
3518      * UncheckedIOException} which will be thrown from the method that caused
3519      * the access to take place.
3520      *
3521      * @param   start
3522      *          the starting file
3523      * @param   maxDepth
3524      *          the maximum number of directory levels to search
3525      * @param   matcher
3526      *          the function used to decide whether a file should be included
3527      *          in the returned stream
3528      * @param   options
3529      *          options to configure the traversal
3530      *
3531      * @return  the {@link Stream} of {@link Path}
3532      *
3533      * @throws  IllegalArgumentException
3534      *          if the {@code maxDepth} parameter is negative
3535      * @throws  SecurityException
3536      *          If the security manager denies access to the starting file.
3537      *          In the case of the default provider, the {@link
3538      *          SecurityManager#checkRead(String) checkRead} method is invoked
3539      *          to check read access to the directory.
3540      * @throws  IOException
3541      *          if an I/O error is thrown when accessing the starting file.
3542      *
3543      * @see     #walk(Path, int, FileVisitOption...)
3544      * @since   1.8
3545      */
3546     public static Stream<Path> find(Path start,
3547                                     int maxDepth,
3548                                     BiPredicate<Path, BasicFileAttributes> matcher,
3549                                     FileVisitOption... options)
3550             throws IOException {

3551         FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
3552         try {
3553             return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
3554                                 .onClose(iterator::close)
3555                                 .filter(entry -> matcher.test(entry.file(), entry.attributes()))
3556                                 .map(entry -> entry.file());
3557         } catch (Error|RuntimeException e) {
3558             iterator.close();
3559             throw e;
3560         }
3561     }
3562 
3563     /**
3564      * Read all lines from a file as a {@code Stream}.  Unlike {@link
3565      * #readAllLines(Path, Charset) readAllLines}, this method does not read
3566      * all lines into a {@code List}, but instead populates lazily as the stream
3567      * is consumed.
3568      *
3569      * <p> Bytes from the file are decoded into characters using the specified
3570      * charset and the same line terminators as specified by {@code
3571      * readAllLines} are supported.
3572      *
3573      * <p> After this method returns, then any subsequent I/O exception that
3574      * occurs while reading from the file or when a malformed or unmappable byte
3575      * sequence is read, is wrapped in an {@link UncheckedIOException} that will
3576      * be thrown from the
3577      * {@link java.util.stream.Stream} method that caused the read to take
3578      * place. In case an {@code IOException} is thrown when closing the file,
3579      * it is also wrapped as an {@code UncheckedIOException}.
3580      *
3581      * <p> The returned stream encapsulates a {@link Reader}.  If timely
3582      * disposal of file system resources is required, the try-with-resources
3583      * construct should be used to ensure that the stream's
3584      * {@link Stream#close close} method is invoked after the stream operations
3585      * are completed.
3586      *
3587      *
3588      * @param   path
3589      *          the path to the file
3590      * @param   cs
3591      *          the charset to use for decoding
3592      *
3593      * @return  the lines from the file as a {@code Stream}
3594      *
3595      * @throws  IOException
3596      *          if an I/O error occurs opening the file
3597      * @throws  SecurityException
3598      *          In the case of the default provider, and a security manager is
3599      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
3600      *          method is invoked to check read access to the file.
3601      *
3602      * @see     #readAllLines(Path, Charset)
3603      * @see     #newBufferedReader(Path, Charset)
3604      * @see     java.io.BufferedReader#lines()
3605      * @since   1.8
3606      */
3607     public static Stream<String> lines(Path path, Charset cs) throws IOException {


3608         BufferedReader br = Files.newBufferedReader(path, cs);
3609         try {
3610             return br.lines().onClose(asUncheckedRunnable(br));
3611         } catch (Error|RuntimeException e) {
3612             try {
3613                 br.close();
3614             } catch (IOException ex) {
3615                 try {
3616                     e.addSuppressed(ex);
3617                 } catch (Throwable ignore) {}
3618             }
3619             throw e;
3620         }
3621     }
3622 }