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); |