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

Print this page
rev 7023 : 8006884: (fs) Add Files.list, lines and find
Reviewed-by:
Contributed-by: alan.bateman@oracle.com, henry.jen@oracle.com


  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.SeekableByteChannel;

  32 import java.io.InputStream;
  33 import java.io.OutputStream;
  34 import java.io.Reader;
  35 import java.io.Writer;
  36 import java.io.BufferedReader;
  37 import java.io.BufferedWriter;
  38 import java.io.InputStreamReader;
  39 import java.io.OutputStreamWriter;
  40 import java.io.IOException;

  41 import java.util.*;





  42 import java.security.AccessController;
  43 import java.security.PrivilegedAction;
  44 import java.nio.charset.Charset;
  45 import java.nio.charset.CharsetDecoder;
  46 import java.nio.charset.CharsetEncoder;
  47 
  48 /**
  49  * This class consists exclusively of static methods that operate on files,
  50  * directories, or other types of files.
  51  *
  52  * <p> In most cases, the methods defined here will delegate to the associated
  53  * file system provider to perform the file operations.
  54  *
  55  * @since 1.7
  56  */
  57 
  58 public final class Files {
  59     private Files() { }
  60 
  61     /**


2570      *          the file visitor to invoke for each file
2571      *
2572      * @return  the starting file
2573      *
2574      * @throws  IllegalArgumentException
2575      *          if the {@code maxDepth} parameter is negative
2576      * @throws  SecurityException
2577      *          If the security manager denies access to the starting file.
2578      *          In the case of the default provider, the {@link
2579      *          SecurityManager#checkRead(String) checkRead} method is invoked
2580      *          to check read access to the directory.
2581      * @throws  IOException
2582      *          if an I/O error is thrown by a visitor method
2583      */
2584     public static Path walkFileTree(Path start,
2585                                     Set<FileVisitOption> options,
2586                                     int maxDepth,
2587                                     FileVisitor<? super Path> visitor)
2588         throws IOException
2589     {
2590         if (maxDepth < 0)
2591             throw new IllegalArgumentException("'maxDepth' is negative");
2592 
2593         /**
2594          * Create a FileTreeWalker to walk the file tree, invoking the visitor
2595          * for each event.
2596          */
2597         try (FileTreeWalker walker = new FileTreeWalker(options, maxDepth)) {
2598             FileTreeWalker.Event ev = walker.walk(start);
2599             do {
2600                 FileVisitResult result;
2601                 switch (ev.type()) {
2602                     case ENTRY :
2603                         IOException ioe = ev.ioeException();
2604                         if (ioe == null) {
2605                             assert ev.attributes() != null;
2606                             result = visitor.visitFile(ev.file(), ev.attributes());
2607                         } else {
2608                             result = visitor.visitFileFailed(ev.file(), ioe);
2609                         }
2610                         break;
2611 
2612                     case START_DIRECTORY :


3159      * @throws  SecurityException
3160      *          In the case of the default provider, and a security manager is
3161      *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
3162      *          method is invoked to check write access to the file.
3163      */
3164     public static Path write(Path path, Iterable<? extends CharSequence> lines,
3165                              Charset cs, OpenOption... options)
3166         throws IOException
3167     {
3168         // ensure lines is not null before opening file
3169         Objects.requireNonNull(lines);
3170         CharsetEncoder encoder = cs.newEncoder();
3171         OutputStream out = newOutputStream(path, options);
3172         try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
3173             for (CharSequence line: lines) {
3174                 writer.append(line);
3175                 writer.newLine();
3176             }
3177         }
3178         return path;










































































































































































































































































































































3179     }
3180 }


  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.SeekableByteChannel;
  32 import java.io.Closeable;
  33 import java.io.InputStream;
  34 import java.io.OutputStream;
  35 import java.io.Reader;
  36 import java.io.Writer;
  37 import java.io.BufferedReader;
  38 import java.io.BufferedWriter;
  39 import java.io.InputStreamReader;
  40 import java.io.OutputStreamWriter;
  41 import java.io.IOException;
  42 import java.io.UncheckedIOException;
  43 import java.util.*;
  44 import java.util.function.BiPredicate;
  45 import java.util.stream.CloseableStream;
  46 import java.util.stream.DelegatingStream;
  47 import java.util.stream.Stream;
  48 import java.util.stream.StreamSupport;
  49 import java.security.AccessController;
  50 import java.security.PrivilegedAction;
  51 import java.nio.charset.Charset;
  52 import java.nio.charset.CharsetDecoder;
  53 import java.nio.charset.CharsetEncoder;
  54 
  55 /**
  56  * This class consists exclusively of static methods that operate on files,
  57  * directories, or other types of files.
  58  *
  59  * <p> In most cases, the methods defined here will delegate to the associated
  60  * file system provider to perform the file operations.
  61  *
  62  * @since 1.7
  63  */
  64 
  65 public final class Files {
  66     private Files() { }
  67 
  68     /**


2577      *          the file visitor to invoke for each file
2578      *
2579      * @return  the starting file
2580      *
2581      * @throws  IllegalArgumentException
2582      *          if the {@code maxDepth} parameter is negative
2583      * @throws  SecurityException
2584      *          If the security manager denies access to the starting file.
2585      *          In the case of the default provider, the {@link
2586      *          SecurityManager#checkRead(String) checkRead} method is invoked
2587      *          to check read access to the directory.
2588      * @throws  IOException
2589      *          if an I/O error is thrown by a visitor method
2590      */
2591     public static Path walkFileTree(Path start,
2592                                     Set<FileVisitOption> options,
2593                                     int maxDepth,
2594                                     FileVisitor<? super Path> visitor)
2595         throws IOException
2596     {



2597         /**
2598          * Create a FileTreeWalker to walk the file tree, invoking the visitor
2599          * for each event.
2600          */
2601         try (FileTreeWalker walker = new FileTreeWalker(options, maxDepth)) {
2602             FileTreeWalker.Event ev = walker.walk(start);
2603             do {
2604                 FileVisitResult result;
2605                 switch (ev.type()) {
2606                     case ENTRY :
2607                         IOException ioe = ev.ioeException();
2608                         if (ioe == null) {
2609                             assert ev.attributes() != null;
2610                             result = visitor.visitFile(ev.file(), ev.attributes());
2611                         } else {
2612                             result = visitor.visitFileFailed(ev.file(), ioe);
2613                         }
2614                         break;
2615 
2616                     case START_DIRECTORY :


3163      * @throws  SecurityException
3164      *          In the case of the default provider, and a security manager is
3165      *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
3166      *          method is invoked to check write access to the file.
3167      */
3168     public static Path write(Path path, Iterable<? extends CharSequence> lines,
3169                              Charset cs, OpenOption... options)
3170         throws IOException
3171     {
3172         // ensure lines is not null before opening file
3173         Objects.requireNonNull(lines);
3174         CharsetEncoder encoder = cs.newEncoder();
3175         OutputStream out = newOutputStream(path, options);
3176         try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
3177             for (CharSequence line: lines) {
3178                 writer.append(line);
3179                 writer.newLine();
3180             }
3181         }
3182         return path;
3183     }
3184 
3185     // -- Stream APIs --
3186 
3187     /**
3188      * Implementation of CloseableStream
3189      */
3190     private static class DelegatingCloseableStream<T> extends DelegatingStream<T>
3191         implements CloseableStream<T>
3192     {
3193         private final Closeable closeable;
3194 
3195         DelegatingCloseableStream(Closeable c, Stream<T> delegate) {
3196             super(delegate);
3197             this.closeable = c;
3198         }
3199 
3200         public void close() {
3201             try {
3202                 closeable.close();
3203             } catch (IOException ex) {
3204                 throw new UncheckedIOException(ex);
3205             }
3206         }
3207     }
3208 
3209     /**
3210      * Return a lazily populated {@code CloseableStream}, the elements of
3211      * which are the entries in the directory.  The listing is not recursive.
3212      *
3213      * <p> The elements of the stream are {@link Path} objects that are obtained
3214      * as if by {@link Path#resolve(Path) resolving} the name of the directory
3215      * entry against {@code dir}. Some file systems maintain special links to
3216      * the directory itself and the directory's parent directory. Entries
3217      * representing these links are not included.
3218      *
3219      * <p> The stream is <i>weakly consistent</i>. It is thread safe but does
3220      * not freeze the directory while iterating, so it may (or may not)
3221      * reflect updates to the directory that occur after returned from this
3222      * method.
3223      *
3224      * <p> When not using the try-with-resources construct, then stream's
3225      * {@link CloseableStream#close close} method should be invoked after
3226      * operation is completed so as to free any resources held for the open
3227      * directory.
3228      *
3229      * <p> If an {@link IOException} is thrown when accessing the directory
3230      * after this method has returned, it is wrapped in an {@link
3231      * UncheckedIOException} which will be thrown from the method that caused
3232      * the access to take place.
3233      *
3234      * @param   dir  The path to the directory
3235      *
3236      * @return  The {@code CloseableStream} describing the content of the
3237      *          directory
3238      *
3239      * @throws  NotDirectoryException
3240      *          if the file could not otherwise be opened because it is not
3241      *          a directory <i>(optional specific exception)</i>
3242      * @throws  IOException
3243      *          if an I/O error occurs when opening the directory
3244      * @throws  SecurityException
3245      *          In the case of the default provider, and a security manager is
3246      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
3247      *          method is invoked to check read access to the directory.
3248      *
3249      * @see     #newDirectoryStream(Path)
3250      * @see     DirectoryStream#entries()
3251      * @since   1.8
3252      */
3253     public static CloseableStream<Path> list(Path dir) throws IOException {
3254         DirectoryStream<Path> ds = Files.newDirectoryStream(dir);
3255         final Iterator<Path> delegate = ds.iterator();
3256 
3257         // Re-wrap DirectoryIteratorException to UncheckedIOException
3258         Iterator<Path> it = new Iterator<Path>() {
3259             public boolean hasNext() {
3260                 try {
3261                     return delegate.hasNext();
3262                 } catch (DirectoryIteratorException e) {
3263                     throw new UncheckedIOException(e.getCause());
3264                 }
3265             }
3266             public Path next() {
3267                 try {
3268                     return delegate.next();
3269                 } catch (DirectoryIteratorException e) {
3270                     throw new UncheckedIOException(e.getCause());
3271                 }
3272             }
3273         };
3274 
3275         return new DelegatingCloseableStream<>(ds,
3276             StreamSupport.stream(Spliterators.spliteratorUnknownSize(it,
3277                                                                      Spliterator.DISTINCT)));
3278     }
3279 
3280     /**
3281      * Return a {@code CloseableStream} that is lazily populated with {@code
3282      * Path} by walking the file tree rooted at a given starting file.  The
3283      * file tree is traversed <em>depth-first</em>, the elements in the stream
3284      * are {@link Path} objects that are obtained as if by {@link
3285      * Path#resolve(Path) resolving} the relative path against {@code start}.
3286      *
3287      * <p> The {@code stream} walks the file tree as elements are consumed.
3288      * The {@code CloseableStream} returned is guaranteed to have at least one
3289      * element, the starting file itself. For each file visited, the stream
3290      * attempts to read its {@link BasicFileAttributes}. If the file is a
3291      * directory and can be opened successfully, entries in the directory, and
3292      * their <em>descendants</em> will follow the directory in the stream as
3293      * they are encountered. When all entries have been visited, then the
3294      * directory is closed. The file tree walk then continues at the next
3295      * <em>sibling</em> of the directory.
3296      *
3297      * <p> The stream is <i>weakly consistent</i>. It does not freeze the
3298      * file tree while iterating, so it may (or may not) reflect updates to
3299      * the file tree that occur after returned from this method.
3300      *
3301      * <p> By default, symbolic links are not automatically followed by this
3302      * method. If the {@code options} parameter contains the {@link
3303      * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
3304      * followed. When following links, and the attributes of the target cannot
3305      * be read, then this method attempts to get the {@code BasicFileAttributes}
3306      * of the link.
3307      *
3308      * <p> If the {@code options} parameter contains the {@link
3309      * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then the stream keeps
3310      * track of directories visited so that cycles can be detected. A cycle
3311      * arises when there is an entry in a directory that is an ancestor of the
3312      * directory. Cycle detection is done by recording the {@link
3313      * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
3314      * or if file keys are not available, by invoking the {@link #isSameFile
3315      * isSameFile} method to test if a directory is the same file as an
3316      * ancestor. When a cycle is detected it is treated as an I/O error with
3317      * an instance of {@link FileSystemLoopException}.
3318      *
3319      * <p> The {@code maxDepth} parameter is the maximum number of levels of
3320      * directories to visit. A value of {@code 0} means that only the starting
3321      * file is visited, unless denied by the security manager. A value of
3322      * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
3323      * levels should be visited.
3324      *
3325      * <p> When a security manager is installed and it denies access to a file
3326      * (or directory), then it is ignored and not included in the stream.
3327      *
3328      * <p> When not using the try-with-resources construct, then stream's
3329      * {@link CloseableStream#close close} method should be invoked after
3330      * operation is completed so as to free any resources held for the open
3331      * directory.
3332      *
3333      * <p> If an {@link IOException} is thrown when accessing the directory
3334      * after this method has returned, it is wrapped in an {@link
3335      * UncheckedIOException} which will be thrown from the method that caused
3336      * the access to take place.
3337      *
3338      * @param   start
3339      *          the starting file
3340      * @param   maxDepth
3341      *          the maximum number of directory levels to visit
3342      * @param   options
3343      *          options to configure the traversal
3344      *
3345      * @return  the {@link CloseableStream} of {@link Path}
3346      *
3347      * @throws  IllegalArgumentException
3348      *          if the {@code maxDepth} parameter is negative
3349      * @throws  SecurityException
3350      *          If the security manager denies access to the starting file.
3351      *          In the case of the default provider, the {@link
3352      *          SecurityManager#checkRead(String) checkRead} method is invoked
3353      *          to check read access to the directory.
3354      * @throws  IOException
3355      *          if an I/O error is thrown when accessing the starting file.
3356      * @since   1.8
3357      */
3358     public static CloseableStream<Path> walk(Path start, int maxDepth,
3359                                              FileVisitOption... options)
3360         throws IOException
3361     {
3362         FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
3363         return new DelegatingCloseableStream<>(iterator,
3364             StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT))
3365                    .map(entry -> entry.file()));
3366     }
3367 
3368     /**
3369      * Return a {@code CloseableStream} that is lazily populated with {@code
3370      * Path} by walking the file tree rooted at a given starting file.  The
3371      * file tree is traversed <em>depth-first</em>, the elements in the stream
3372      * are {@link Path} objects that are obtained as if by {@link
3373      * Path#resolve(Path) resolving} the relative path against {@code start}.
3374      *
3375      * <p> This method works as if invoking it were equivalent to evaluating the
3376      * expression:
3377      * <blockquote><pre>
3378      * walk(start, Integer.MAX_VALUE, options)
3379      * </pre></blockquote>
3380      * In other words, it visits all levels of the file tree.
3381      *
3382      * @param   start
3383      *          the starting file
3384      * @param   options
3385      *          options to configure the traversal
3386      *
3387      * @return  the {@link CloseableStream} of {@link Path}
3388      *
3389      * @throws  SecurityException
3390      *          If the security manager denies access to the starting file.
3391      *          In the case of the default provider, the {@link
3392      *          SecurityManager#checkRead(String) checkRead} method is invoked
3393      *          to check read access to the directory.
3394      * @throws  IOException
3395      *          if an I/O error is thrown when accessing the starting file.
3396      *
3397      * @see     #walk(Path, int, FileVisitOption...)
3398      * @since   1.8
3399      */
3400     public static CloseableStream<Path> walk(Path start,
3401                                              FileVisitOption... options)
3402         throws IOException
3403     {
3404         return walk(start, Integer.MAX_VALUE, options);
3405     }
3406 
3407     /**
3408      * Return a {@code CloseableStream} that is lazily populated with {@code
3409      * Path} by searching for files in a file tree rooted at a given starting
3410      * file.
3411      *
3412      * <p>This method walks the file tree in exactly the manner specified by
3413      * the {@link #walk walk} method. For each file encountered, the given
3414      * {@link BiPredicate} is invoked with its {@link Path} and {@link
3415      * BasicFileAttributes}. The {@code Path} object is obtained as if by
3416      * {@link Path#resolve(Path) resolving} the relative path against {@code
3417      * start} and is only included in the returned {@link CloseableStream} if
3418      * the {@code BiPredicate} returns true. Compare to calling {@link
3419      * java.util.stream.Stream#filter filter} on the {@code Stream} returned
3420      * by {@code walk} method, this method is more efficient by avoiding
3421      * redundant retrieval of the {@code BasicFileAttributes}.
3422      *
3423      * <p>If an {@link IOException} is thrown when accessing the directory
3424      * after returned from this method, it is wrapped in an {@link
3425      * UncheckedIOException} which will be thrown from the method that caused
3426      * the access to take place.
3427      *
3428      * @param   start
3429      *          the starting file
3430      * @param   maxDepth
3431      *          the maximum number of directory levels to search
3432      * @param   matcher
3433      *          the function used to decide whether a file should be included
3434      *          in the returned stream
3435      * @param   options
3436      *          options to configure the traversal
3437      *
3438      * @return  the {@link CloseableStream} of {@link Path}
3439      *
3440      * @throws  IllegalArgumentException
3441      *          if the {@code maxDepth} parameter is negative
3442      * @throws  SecurityException
3443      *          If the security manager denies access to the starting file.
3444      *          In the case of the default provider, the {@link
3445      *          SecurityManager#checkRead(String) checkRead} method is invoked
3446      *          to check read access to the directory.
3447      * @throws  IOException
3448      *          if an I/O error is thrown when accessing the starting file.
3449      *
3450      * @see     #walk(Path, int, FileVisitOption...)
3451      * @since   1.8
3452      */
3453     public static CloseableStream<Path> find(Path start,
3454                                              int maxDepth,
3455                                              BiPredicate<Path, BasicFileAttributes> matcher,
3456                                              FileVisitOption... options)
3457         throws IOException
3458     {
3459         FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
3460         return new DelegatingCloseableStream<>(iterator,
3461             StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT))
3462                    .filter(entry -> matcher.test(entry.file(), entry.attributes()))
3463                    .map(entry -> entry.file()));
3464     }
3465 
3466     /**
3467      * Read all lines from a file as a {@code CloseableStream}.  Unlike {@link
3468      * #readAllLines(Path, Charset) readAllLines}, this method does not read
3469      * all lines into a {@code List}, but instead populates lazily as the stream
3470      * is consumed.
3471      *
3472      * <p> Bytes from the file are decoded into characters using the specified
3473      * charset and the same line terminators as specified by {@code
3474      * readAllLines} are supported.
3475      *
3476      * <p> After this method returns, then any subsequent I/O exception that
3477      * occurs while reading from the file or when a malformed or unmappable byte
3478      * sequence is read, is wrapped in an {@link UncheckedIOException} that will
3479      * be thrown form the
3480      * {@link java.util.stream.Stream} method that caused the read to take
3481      * place. In case an {@code IOException} is thrown when closing the file,
3482      * it is also wrapped as an {@code UncheckedIOException}.
3483      *
3484      * <p> When not using the try-with-resources construct, then stream's
3485      * {@link CloseableStream#close close} method should be invoked after
3486      * operation is completed so as to free any resources held for the open
3487      * file.
3488      *
3489      * @param   path
3490      *          the path to the file
3491      * @param   cs
3492      *          the charset to use for decoding
3493      *
3494      * @return  the lines from the file as a {@code CloseableStream}
3495      *
3496      * @throws  IOException
3497      *          if an I/O error occurs opening the file
3498      * @throws  SecurityException
3499      *          In the case of the default provider, and a security manager is
3500      *          installed, the {@link SecurityManager#checkRead(String) checkRead}
3501      *          method is invoked to check read access to the file.
3502      *
3503      * @see     #readAllLines(Path, Charset)
3504      * @see     #newBufferedReader(Path, Charset)
3505      * @see     java.io.BufferedReader#lines()
3506      * @since   1.8
3507      */
3508     public static CloseableStream<String> lines(Path path, Charset cs)
3509         throws IOException
3510     {
3511         BufferedReader br = Files.newBufferedReader(path, cs);
3512         return new DelegatingCloseableStream<>(br, br.lines());
3513     }
3514 }