jdk/src/share/classes/java/nio/file/FileTreeWalker.java
changeset 2071 5e6af6d106cb
parent 2057 3acf8e5e2ca0
child 3065 452aaa2899fc
equal deleted inserted replaced
2069:2cd4a0aa917f 2071:5e6af6d106cb
    26 package java.nio.file;
    26 package java.nio.file;
    27 
    27 
    28 import java.nio.file.attribute.*;
    28 import java.nio.file.attribute.*;
    29 import java.io.IOException;
    29 import java.io.IOException;
    30 import java.util.*;
    30 import java.util.*;
       
    31 import sun.nio.fs.BasicFileAttributesHolder;
    31 
    32 
    32 /**
    33 /**
    33  * Simple file tree walker that works in a similar manner to nftw(3C).
    34  * Simple file tree walker that works in a similar manner to nftw(3C).
    34  *
    35  *
    35  * @see Files#walkFileTree
    36  * @see Files#walkFileTree
    63 
    64 
    64     /**
    65     /**
    65      * Walk file tree starting at the given file
    66      * Walk file tree starting at the given file
    66      */
    67      */
    67     void walk(Path start, int maxDepth) {
    68     void walk(Path start, int maxDepth) {
       
    69         // don't use attributes of starting file as they may be stale
       
    70         if (start instanceof BasicFileAttributesHolder) {
       
    71             ((BasicFileAttributesHolder)start).invalidate();
       
    72         }
    68         FileVisitResult result = walk(start,
    73         FileVisitResult result = walk(start,
    69                                       maxDepth,
    74                                       maxDepth,
    70                                       new ArrayList<AncestorDirectory>());
    75                                       new ArrayList<AncestorDirectory>());
    71         if (result == null) {
    76         if (result == null) {
    72             throw new NullPointerException("Visitor returned 'null'");
    77             throw new NullPointerException("Visitor returned 'null'");
    73         }
    78         }
    74     }
    79     }
    75 
    80 
    76     /**
    81     /**
    77      * @param   file
    82      * @param   file
    78      *          The directory to visit
    83      *          the directory to visit
    79      * @param   path
       
    80      *          list of directories that is relative path from starting file
       
    81      * @param   depth
    84      * @param   depth
    82      *          Depth remaining
    85      *          depth remaining
    83      * @param   ancestors
    86      * @param   ancestors
    84      *          use when cycle detection is enabled
    87      *          use when cycle detection is enabled
    85      */
    88      */
    86     private FileVisitResult walk(Path file,
    89     private FileVisitResult walk(Path file,
    87                                  int depth,
    90                                  int depth,
    89     {
    92     {
    90         // depth check
    93         // depth check
    91         if (depth-- < 0)
    94         if (depth-- < 0)
    92             return FileVisitResult.CONTINUE;
    95             return FileVisitResult.CONTINUE;
    93 
    96 
       
    97         // if attributes are cached then use them if possible
    94         BasicFileAttributes attrs = null;
    98         BasicFileAttributes attrs = null;
       
    99         if (file instanceof BasicFileAttributesHolder) {
       
   100             BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
       
   101             if (!followLinks || !cached.isSymbolicLink())
       
   102                 attrs = cached;
       
   103         }
    95         IOException exc = null;
   104         IOException exc = null;
    96 
   105 
    97         // attempt to get attributes of file. If fails and we are following
   106         // attempt to get attributes of file. If fails and we are following
    98         // links then a link target might not exist so get attributes of link
   107         // links then a link target might not exist so get attributes of link
    99         try {
   108         if (attrs == null) {
   100             try {
   109             try {
   101                 attrs = Attributes.readBasicFileAttributes(file, linkOptions);
   110                 try {
   102             } catch (IOException x1) {
   111                     attrs = Attributes.readBasicFileAttributes(file, linkOptions);
   103                 if (followLinks) {
   112                 } catch (IOException x1) {
   104                     try {
   113                     if (followLinks) {
   105                         attrs = Attributes
   114                         try {
   106                             .readBasicFileAttributes(file, LinkOption.NOFOLLOW_LINKS);
   115                             attrs = Attributes
   107                     } catch (IOException x2) {
   116                                 .readBasicFileAttributes(file, LinkOption.NOFOLLOW_LINKS);
   108                         exc = x2;
   117                         } catch (IOException x2) {
   109                     }
   118                             exc = x2;
   110                 } else {
   119                         }
   111                     exc = x1;
   120                     } else {
   112                 }
   121                         exc = x1;
   113             }
   122                     }
   114         } catch (SecurityException x) {
   123                 }
   115             return FileVisitResult.CONTINUE;
   124             } catch (SecurityException x) {
       
   125                 return FileVisitResult.CONTINUE;
       
   126             }
   116         }
   127         }
   117 
   128 
   118         // unable to get attributes of file
   129         // unable to get attributes of file
   119         if (exc != null) {
   130         if (exc != null) {
   120             return visitor.visitFileFailed(file, exc);
   131             return visitor.visitFileFailed(file, exc);