|
1 /* |
|
2 * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
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.io; |
|
27 |
|
28 import java.net.URI; |
|
29 import java.net.URL; |
|
30 import java.net.MalformedURLException; |
|
31 import java.net.URISyntaxException; |
|
32 import java.util.List; |
|
33 import java.util.ArrayList; |
|
34 import java.security.SecureRandom; |
|
35 import java.nio.file.Path; |
|
36 import java.nio.file.FileSystems; |
|
37 import sun.security.action.GetPropertyAction; |
|
38 |
|
39 /** |
|
40 * An abstract representation of file and directory pathnames. |
|
41 * |
|
42 * <p> User interfaces and operating systems use system-dependent <em>pathname |
|
43 * strings</em> to name files and directories. This class presents an |
|
44 * abstract, system-independent view of hierarchical pathnames. An |
|
45 * <em>abstract pathname</em> has two components: |
|
46 * |
|
47 * <ol> |
|
48 * <li> An optional system-dependent <em>prefix</em> string, |
|
49 * such as a disk-drive specifier, <code>"/"</code> for the UNIX root |
|
50 * directory, or <code>"\\\\"</code> for a Microsoft Windows UNC pathname, and |
|
51 * <li> A sequence of zero or more string <em>names</em>. |
|
52 * </ol> |
|
53 * |
|
54 * The first name in an abstract pathname may be a directory name or, in the |
|
55 * case of Microsoft Windows UNC pathnames, a hostname. Each subsequent name |
|
56 * in an abstract pathname denotes a directory; the last name may denote |
|
57 * either a directory or a file. The <em>empty</em> abstract pathname has no |
|
58 * prefix and an empty name sequence. |
|
59 * |
|
60 * <p> The conversion of a pathname string to or from an abstract pathname is |
|
61 * inherently system-dependent. When an abstract pathname is converted into a |
|
62 * pathname string, each name is separated from the next by a single copy of |
|
63 * the default <em>separator character</em>. The default name-separator |
|
64 * character is defined by the system property <code>file.separator</code>, and |
|
65 * is made available in the public static fields {@link |
|
66 * #separator} and {@link #separatorChar} of this class. |
|
67 * When a pathname string is converted into an abstract pathname, the names |
|
68 * within it may be separated by the default name-separator character or by any |
|
69 * other name-separator character that is supported by the underlying system. |
|
70 * |
|
71 * <p> A pathname, whether abstract or in string form, may be either |
|
72 * <em>absolute</em> or <em>relative</em>. An absolute pathname is complete in |
|
73 * that no other information is required in order to locate the file that it |
|
74 * denotes. A relative pathname, in contrast, must be interpreted in terms of |
|
75 * information taken from some other pathname. By default the classes in the |
|
76 * <code>java.io</code> package always resolve relative pathnames against the |
|
77 * current user directory. This directory is named by the system property |
|
78 * <code>user.dir</code>, and is typically the directory in which the Java |
|
79 * virtual machine was invoked. |
|
80 * |
|
81 * <p> The <em>parent</em> of an abstract pathname may be obtained by invoking |
|
82 * the {@link #getParent} method of this class and consists of the pathname's |
|
83 * prefix and each name in the pathname's name sequence except for the last. |
|
84 * Each directory's absolute pathname is an ancestor of any {@code File} |
|
85 * object with an absolute abstract pathname which begins with the directory's |
|
86 * absolute pathname. For example, the directory denoted by the abstract |
|
87 * pathname {@code "/usr"} is an ancestor of the directory denoted by the |
|
88 * pathname {@code "/usr/local/bin"}. |
|
89 * |
|
90 * <p> The prefix concept is used to handle root directories on UNIX platforms, |
|
91 * and drive specifiers, root directories and UNC pathnames on Microsoft Windows platforms, |
|
92 * as follows: |
|
93 * |
|
94 * <ul> |
|
95 * |
|
96 * <li> For UNIX platforms, the prefix of an absolute pathname is always |
|
97 * <code>"/"</code>. Relative pathnames have no prefix. The abstract pathname |
|
98 * denoting the root directory has the prefix <code>"/"</code> and an empty |
|
99 * name sequence. |
|
100 * |
|
101 * <li> For Microsoft Windows platforms, the prefix of a pathname that contains a drive |
|
102 * specifier consists of the drive letter followed by <code>":"</code> and |
|
103 * possibly followed by <code>"\\"</code> if the pathname is absolute. The |
|
104 * prefix of a UNC pathname is <code>"\\\\"</code>; the hostname and the share |
|
105 * name are the first two names in the name sequence. A relative pathname that |
|
106 * does not specify a drive has no prefix. |
|
107 * |
|
108 * </ul> |
|
109 * |
|
110 * <p> Instances of this class may or may not denote an actual file-system |
|
111 * object such as a file or a directory. If it does denote such an object |
|
112 * then that object resides in a <i>partition</i>. A partition is an |
|
113 * operating system-specific portion of storage for a file system. A single |
|
114 * storage device (e.g. a physical disk-drive, flash memory, CD-ROM) may |
|
115 * contain multiple partitions. The object, if any, will reside on the |
|
116 * partition <a id="partName">named</a> by some ancestor of the absolute |
|
117 * form of this pathname. |
|
118 * |
|
119 * <p> A file system may implement restrictions to certain operations on the |
|
120 * actual file-system object, such as reading, writing, and executing. These |
|
121 * restrictions are collectively known as <i>access permissions</i>. The file |
|
122 * system may have multiple sets of access permissions on a single object. |
|
123 * For example, one set may apply to the object's <i>owner</i>, and another |
|
124 * may apply to all other users. The access permissions on an object may |
|
125 * cause some methods in this class to fail. |
|
126 * |
|
127 * <p> Instances of the <code>File</code> class are immutable; that is, once |
|
128 * created, the abstract pathname represented by a <code>File</code> object |
|
129 * will never change. |
|
130 * |
|
131 * <h3>Interoperability with {@code java.nio.file} package</h3> |
|
132 * |
|
133 * <p> The <a href="../../java/nio/file/package-summary.html">{@code java.nio.file}</a> |
|
134 * package defines interfaces and classes for the Java virtual machine to access |
|
135 * files, file attributes, and file systems. This API may be used to overcome |
|
136 * many of the limitations of the {@code java.io.File} class. |
|
137 * The {@link #toPath toPath} method may be used to obtain a {@link |
|
138 * Path} that uses the abstract path represented by a {@code File} object to |
|
139 * locate a file. The resulting {@code Path} may be used with the {@link |
|
140 * java.nio.file.Files} class to provide more efficient and extensive access to |
|
141 * additional file operations, file attributes, and I/O exceptions to help |
|
142 * diagnose errors when an operation on a file fails. |
|
143 * |
|
144 * @author unascribed |
|
145 * @since 1.0 |
|
146 */ |
|
147 |
|
148 public class File |
|
149 implements Serializable, Comparable<File> |
|
150 { |
|
151 |
|
152 /** |
|
153 * The FileSystem object representing the platform's local file system. |
|
154 */ |
|
155 private static final FileSystem fs = DefaultFileSystem.getFileSystem(); |
|
156 |
|
157 /** |
|
158 * This abstract pathname's normalized pathname string. A normalized |
|
159 * pathname string uses the default name-separator character and does not |
|
160 * contain any duplicate or redundant separators. |
|
161 * |
|
162 * @serial |
|
163 */ |
|
164 private final String path; |
|
165 |
|
166 /** |
|
167 * Enum type that indicates the status of a file path. |
|
168 */ |
|
169 private static enum PathStatus { INVALID, CHECKED }; |
|
170 |
|
171 /** |
|
172 * The flag indicating whether the file path is invalid. |
|
173 */ |
|
174 private transient PathStatus status = null; |
|
175 |
|
176 /** |
|
177 * Check if the file has an invalid path. Currently, the inspection of |
|
178 * a file path is very limited, and it only covers Nul character check. |
|
179 * Returning true means the path is definitely invalid/garbage. But |
|
180 * returning false does not guarantee that the path is valid. |
|
181 * |
|
182 * @return true if the file path is invalid. |
|
183 */ |
|
184 final boolean isInvalid() { |
|
185 if (status == null) { |
|
186 status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED |
|
187 : PathStatus.INVALID; |
|
188 } |
|
189 return status == PathStatus.INVALID; |
|
190 } |
|
191 |
|
192 /** |
|
193 * The length of this abstract pathname's prefix, or zero if it has no |
|
194 * prefix. |
|
195 */ |
|
196 private final transient int prefixLength; |
|
197 |
|
198 /** |
|
199 * Returns the length of this abstract pathname's prefix. |
|
200 * For use by FileSystem classes. |
|
201 */ |
|
202 int getPrefixLength() { |
|
203 return prefixLength; |
|
204 } |
|
205 |
|
206 /** |
|
207 * The system-dependent default name-separator character. This field is |
|
208 * initialized to contain the first character of the value of the system |
|
209 * property <code>file.separator</code>. On UNIX systems the value of this |
|
210 * field is <code>'/'</code>; on Microsoft Windows systems it is <code>'\\'</code>. |
|
211 * |
|
212 * @see java.lang.System#getProperty(java.lang.String) |
|
213 */ |
|
214 public static final char separatorChar = fs.getSeparator(); |
|
215 |
|
216 /** |
|
217 * The system-dependent default name-separator character, represented as a |
|
218 * string for convenience. This string contains a single character, namely |
|
219 * {@link #separatorChar}. |
|
220 */ |
|
221 public static final String separator = "" + separatorChar; |
|
222 |
|
223 /** |
|
224 * The system-dependent path-separator character. This field is |
|
225 * initialized to contain the first character of the value of the system |
|
226 * property <code>path.separator</code>. This character is used to |
|
227 * separate filenames in a sequence of files given as a <em>path list</em>. |
|
228 * On UNIX systems, this character is <code>':'</code>; on Microsoft Windows systems it |
|
229 * is <code>';'</code>. |
|
230 * |
|
231 * @see java.lang.System#getProperty(java.lang.String) |
|
232 */ |
|
233 public static final char pathSeparatorChar = fs.getPathSeparator(); |
|
234 |
|
235 /** |
|
236 * The system-dependent path-separator character, represented as a string |
|
237 * for convenience. This string contains a single character, namely |
|
238 * {@link #pathSeparatorChar}. |
|
239 */ |
|
240 public static final String pathSeparator = "" + pathSeparatorChar; |
|
241 |
|
242 |
|
243 /* -- Constructors -- */ |
|
244 |
|
245 /** |
|
246 * Internal constructor for already-normalized pathname strings. |
|
247 */ |
|
248 private File(String pathname, int prefixLength) { |
|
249 this.path = pathname; |
|
250 this.prefixLength = prefixLength; |
|
251 } |
|
252 |
|
253 /** |
|
254 * Internal constructor for already-normalized pathname strings. |
|
255 * The parameter order is used to disambiguate this method from the |
|
256 * public(File, String) constructor. |
|
257 */ |
|
258 private File(String child, File parent) { |
|
259 assert parent.path != null; |
|
260 assert (!parent.path.equals("")); |
|
261 this.path = fs.resolve(parent.path, child); |
|
262 this.prefixLength = parent.prefixLength; |
|
263 } |
|
264 |
|
265 /** |
|
266 * Creates a new <code>File</code> instance by converting the given |
|
267 * pathname string into an abstract pathname. If the given string is |
|
268 * the empty string, then the result is the empty abstract pathname. |
|
269 * |
|
270 * @param pathname A pathname string |
|
271 * @throws NullPointerException |
|
272 * If the <code>pathname</code> argument is <code>null</code> |
|
273 */ |
|
274 public File(String pathname) { |
|
275 if (pathname == null) { |
|
276 throw new NullPointerException(); |
|
277 } |
|
278 this.path = fs.normalize(pathname); |
|
279 this.prefixLength = fs.prefixLength(this.path); |
|
280 } |
|
281 |
|
282 /* Note: The two-argument File constructors do not interpret an empty |
|
283 parent abstract pathname as the current user directory. An empty parent |
|
284 instead causes the child to be resolved against the system-dependent |
|
285 directory defined by the FileSystem.getDefaultParent method. On Unix |
|
286 this default is "/", while on Microsoft Windows it is "\\". This is required for |
|
287 compatibility with the original behavior of this class. */ |
|
288 |
|
289 /** |
|
290 * Creates a new <code>File</code> instance from a parent pathname string |
|
291 * and a child pathname string. |
|
292 * |
|
293 * <p> If <code>parent</code> is <code>null</code> then the new |
|
294 * <code>File</code> instance is created as if by invoking the |
|
295 * single-argument <code>File</code> constructor on the given |
|
296 * <code>child</code> pathname string. |
|
297 * |
|
298 * <p> Otherwise the <code>parent</code> pathname string is taken to denote |
|
299 * a directory, and the <code>child</code> pathname string is taken to |
|
300 * denote either a directory or a file. If the <code>child</code> pathname |
|
301 * string is absolute then it is converted into a relative pathname in a |
|
302 * system-dependent way. If <code>parent</code> is the empty string then |
|
303 * the new <code>File</code> instance is created by converting |
|
304 * <code>child</code> into an abstract pathname and resolving the result |
|
305 * against a system-dependent default directory. Otherwise each pathname |
|
306 * string is converted into an abstract pathname and the child abstract |
|
307 * pathname is resolved against the parent. |
|
308 * |
|
309 * @param parent The parent pathname string |
|
310 * @param child The child pathname string |
|
311 * @throws NullPointerException |
|
312 * If <code>child</code> is <code>null</code> |
|
313 */ |
|
314 public File(String parent, String child) { |
|
315 if (child == null) { |
|
316 throw new NullPointerException(); |
|
317 } |
|
318 if (parent != null) { |
|
319 if (parent.equals("")) { |
|
320 this.path = fs.resolve(fs.getDefaultParent(), |
|
321 fs.normalize(child)); |
|
322 } else { |
|
323 this.path = fs.resolve(fs.normalize(parent), |
|
324 fs.normalize(child)); |
|
325 } |
|
326 } else { |
|
327 this.path = fs.normalize(child); |
|
328 } |
|
329 this.prefixLength = fs.prefixLength(this.path); |
|
330 } |
|
331 |
|
332 /** |
|
333 * Creates a new <code>File</code> instance from a parent abstract |
|
334 * pathname and a child pathname string. |
|
335 * |
|
336 * <p> If <code>parent</code> is <code>null</code> then the new |
|
337 * <code>File</code> instance is created as if by invoking the |
|
338 * single-argument <code>File</code> constructor on the given |
|
339 * <code>child</code> pathname string. |
|
340 * |
|
341 * <p> Otherwise the <code>parent</code> abstract pathname is taken to |
|
342 * denote a directory, and the <code>child</code> pathname string is taken |
|
343 * to denote either a directory or a file. If the <code>child</code> |
|
344 * pathname string is absolute then it is converted into a relative |
|
345 * pathname in a system-dependent way. If <code>parent</code> is the empty |
|
346 * abstract pathname then the new <code>File</code> instance is created by |
|
347 * converting <code>child</code> into an abstract pathname and resolving |
|
348 * the result against a system-dependent default directory. Otherwise each |
|
349 * pathname string is converted into an abstract pathname and the child |
|
350 * abstract pathname is resolved against the parent. |
|
351 * |
|
352 * @param parent The parent abstract pathname |
|
353 * @param child The child pathname string |
|
354 * @throws NullPointerException |
|
355 * If <code>child</code> is <code>null</code> |
|
356 */ |
|
357 public File(File parent, String child) { |
|
358 if (child == null) { |
|
359 throw new NullPointerException(); |
|
360 } |
|
361 if (parent != null) { |
|
362 if (parent.path.equals("")) { |
|
363 this.path = fs.resolve(fs.getDefaultParent(), |
|
364 fs.normalize(child)); |
|
365 } else { |
|
366 this.path = fs.resolve(parent.path, |
|
367 fs.normalize(child)); |
|
368 } |
|
369 } else { |
|
370 this.path = fs.normalize(child); |
|
371 } |
|
372 this.prefixLength = fs.prefixLength(this.path); |
|
373 } |
|
374 |
|
375 /** |
|
376 * Creates a new {@code File} instance by converting the given |
|
377 * {@code file:} URI into an abstract pathname. |
|
378 * |
|
379 * <p> The exact form of a {@code file:} URI is system-dependent, hence |
|
380 * the transformation performed by this constructor is also |
|
381 * system-dependent. |
|
382 * |
|
383 * <p> For a given abstract pathname <i>f</i> it is guaranteed that |
|
384 * |
|
385 * <blockquote><code> |
|
386 * new File(</code><i> f</i><code>.{@link #toURI() |
|
387 * toURI}()).equals(</code><i> f</i><code>.{@link #getAbsoluteFile() getAbsoluteFile}()) |
|
388 * </code></blockquote> |
|
389 * |
|
390 * so long as the original abstract pathname, the URI, and the new abstract |
|
391 * pathname are all created in (possibly different invocations of) the same |
|
392 * Java virtual machine. This relationship typically does not hold, |
|
393 * however, when a {@code file:} URI that is created in a virtual machine |
|
394 * on one operating system is converted into an abstract pathname in a |
|
395 * virtual machine on a different operating system. |
|
396 * |
|
397 * @param uri |
|
398 * An absolute, hierarchical URI with a scheme equal to |
|
399 * {@code "file"}, a non-empty path component, and undefined |
|
400 * authority, query, and fragment components |
|
401 * |
|
402 * @throws NullPointerException |
|
403 * If {@code uri} is {@code null} |
|
404 * |
|
405 * @throws IllegalArgumentException |
|
406 * If the preconditions on the parameter do not hold |
|
407 * |
|
408 * @see #toURI() |
|
409 * @see java.net.URI |
|
410 * @since 1.4 |
|
411 */ |
|
412 public File(URI uri) { |
|
413 |
|
414 // Check our many preconditions |
|
415 if (!uri.isAbsolute()) |
|
416 throw new IllegalArgumentException("URI is not absolute"); |
|
417 if (uri.isOpaque()) |
|
418 throw new IllegalArgumentException("URI is not hierarchical"); |
|
419 String scheme = uri.getScheme(); |
|
420 if ((scheme == null) || !scheme.equalsIgnoreCase("file")) |
|
421 throw new IllegalArgumentException("URI scheme is not \"file\""); |
|
422 if (uri.getRawAuthority() != null) |
|
423 throw new IllegalArgumentException("URI has an authority component"); |
|
424 if (uri.getRawFragment() != null) |
|
425 throw new IllegalArgumentException("URI has a fragment component"); |
|
426 if (uri.getRawQuery() != null) |
|
427 throw new IllegalArgumentException("URI has a query component"); |
|
428 String p = uri.getPath(); |
|
429 if (p.equals("")) |
|
430 throw new IllegalArgumentException("URI path component is empty"); |
|
431 |
|
432 // Okay, now initialize |
|
433 p = fs.fromURIPath(p); |
|
434 if (File.separatorChar != '/') |
|
435 p = p.replace('/', File.separatorChar); |
|
436 this.path = fs.normalize(p); |
|
437 this.prefixLength = fs.prefixLength(this.path); |
|
438 } |
|
439 |
|
440 |
|
441 /* -- Path-component accessors -- */ |
|
442 |
|
443 /** |
|
444 * Returns the name of the file or directory denoted by this abstract |
|
445 * pathname. This is just the last name in the pathname's name |
|
446 * sequence. If the pathname's name sequence is empty, then the empty |
|
447 * string is returned. |
|
448 * |
|
449 * @return The name of the file or directory denoted by this abstract |
|
450 * pathname, or the empty string if this pathname's name sequence |
|
451 * is empty |
|
452 */ |
|
453 public String getName() { |
|
454 int index = path.lastIndexOf(separatorChar); |
|
455 if (index < prefixLength) return path.substring(prefixLength); |
|
456 return path.substring(index + 1); |
|
457 } |
|
458 |
|
459 /** |
|
460 * Returns the pathname string of this abstract pathname's parent, or |
|
461 * <code>null</code> if this pathname does not name a parent directory. |
|
462 * |
|
463 * <p> The <em>parent</em> of an abstract pathname consists of the |
|
464 * pathname's prefix, if any, and each name in the pathname's name |
|
465 * sequence except for the last. If the name sequence is empty then |
|
466 * the pathname does not name a parent directory. |
|
467 * |
|
468 * @return The pathname string of the parent directory named by this |
|
469 * abstract pathname, or <code>null</code> if this pathname |
|
470 * does not name a parent |
|
471 */ |
|
472 public String getParent() { |
|
473 int index = path.lastIndexOf(separatorChar); |
|
474 if (index < prefixLength) { |
|
475 if ((prefixLength > 0) && (path.length() > prefixLength)) |
|
476 return path.substring(0, prefixLength); |
|
477 return null; |
|
478 } |
|
479 return path.substring(0, index); |
|
480 } |
|
481 |
|
482 /** |
|
483 * Returns the abstract pathname of this abstract pathname's parent, |
|
484 * or <code>null</code> if this pathname does not name a parent |
|
485 * directory. |
|
486 * |
|
487 * <p> The <em>parent</em> of an abstract pathname consists of the |
|
488 * pathname's prefix, if any, and each name in the pathname's name |
|
489 * sequence except for the last. If the name sequence is empty then |
|
490 * the pathname does not name a parent directory. |
|
491 * |
|
492 * @return The abstract pathname of the parent directory named by this |
|
493 * abstract pathname, or <code>null</code> if this pathname |
|
494 * does not name a parent |
|
495 * |
|
496 * @since 1.2 |
|
497 */ |
|
498 public File getParentFile() { |
|
499 String p = this.getParent(); |
|
500 if (p == null) return null; |
|
501 return new File(p, this.prefixLength); |
|
502 } |
|
503 |
|
504 /** |
|
505 * Converts this abstract pathname into a pathname string. The resulting |
|
506 * string uses the {@link #separator default name-separator character} to |
|
507 * separate the names in the name sequence. |
|
508 * |
|
509 * @return The string form of this abstract pathname |
|
510 */ |
|
511 public String getPath() { |
|
512 return path; |
|
513 } |
|
514 |
|
515 |
|
516 /* -- Path operations -- */ |
|
517 |
|
518 /** |
|
519 * Tests whether this abstract pathname is absolute. The definition of |
|
520 * absolute pathname is system dependent. On UNIX systems, a pathname is |
|
521 * absolute if its prefix is <code>"/"</code>. On Microsoft Windows systems, a |
|
522 * pathname is absolute if its prefix is a drive specifier followed by |
|
523 * <code>"\\"</code>, or if its prefix is <code>"\\\\"</code>. |
|
524 * |
|
525 * @return <code>true</code> if this abstract pathname is absolute, |
|
526 * <code>false</code> otherwise |
|
527 */ |
|
528 public boolean isAbsolute() { |
|
529 return fs.isAbsolute(this); |
|
530 } |
|
531 |
|
532 /** |
|
533 * Returns the absolute pathname string of this abstract pathname. |
|
534 * |
|
535 * <p> If this abstract pathname is already absolute, then the pathname |
|
536 * string is simply returned as if by the {@link #getPath} |
|
537 * method. If this abstract pathname is the empty abstract pathname then |
|
538 * the pathname string of the current user directory, which is named by the |
|
539 * system property <code>user.dir</code>, is returned. Otherwise this |
|
540 * pathname is resolved in a system-dependent way. On UNIX systems, a |
|
541 * relative pathname is made absolute by resolving it against the current |
|
542 * user directory. On Microsoft Windows systems, a relative pathname is made absolute |
|
543 * by resolving it against the current directory of the drive named by the |
|
544 * pathname, if any; if not, it is resolved against the current user |
|
545 * directory. |
|
546 * |
|
547 * @return The absolute pathname string denoting the same file or |
|
548 * directory as this abstract pathname |
|
549 * |
|
550 * @throws SecurityException |
|
551 * If a required system property value cannot be accessed. |
|
552 * |
|
553 * @see java.io.File#isAbsolute() |
|
554 */ |
|
555 public String getAbsolutePath() { |
|
556 return fs.resolve(this); |
|
557 } |
|
558 |
|
559 /** |
|
560 * Returns the absolute form of this abstract pathname. Equivalent to |
|
561 * <code>new File(this.{@link #getAbsolutePath})</code>. |
|
562 * |
|
563 * @return The absolute abstract pathname denoting the same file or |
|
564 * directory as this abstract pathname |
|
565 * |
|
566 * @throws SecurityException |
|
567 * If a required system property value cannot be accessed. |
|
568 * |
|
569 * @since 1.2 |
|
570 */ |
|
571 public File getAbsoluteFile() { |
|
572 String absPath = getAbsolutePath(); |
|
573 return new File(absPath, fs.prefixLength(absPath)); |
|
574 } |
|
575 |
|
576 /** |
|
577 * Returns the canonical pathname string of this abstract pathname. |
|
578 * |
|
579 * <p> A canonical pathname is both absolute and unique. The precise |
|
580 * definition of canonical form is system-dependent. This method first |
|
581 * converts this pathname to absolute form if necessary, as if by invoking the |
|
582 * {@link #getAbsolutePath} method, and then maps it to its unique form in a |
|
583 * system-dependent way. This typically involves removing redundant names |
|
584 * such as {@code "."} and {@code ".."} from the pathname, resolving |
|
585 * symbolic links (on UNIX platforms), and converting drive letters to a |
|
586 * standard case (on Microsoft Windows platforms). |
|
587 * |
|
588 * <p> Every pathname that denotes an existing file or directory has a |
|
589 * unique canonical form. Every pathname that denotes a nonexistent file |
|
590 * or directory also has a unique canonical form. The canonical form of |
|
591 * the pathname of a nonexistent file or directory may be different from |
|
592 * the canonical form of the same pathname after the file or directory is |
|
593 * created. Similarly, the canonical form of the pathname of an existing |
|
594 * file or directory may be different from the canonical form of the same |
|
595 * pathname after the file or directory is deleted. |
|
596 * |
|
597 * @return The canonical pathname string denoting the same file or |
|
598 * directory as this abstract pathname |
|
599 * |
|
600 * @throws IOException |
|
601 * If an I/O error occurs, which is possible because the |
|
602 * construction of the canonical pathname may require |
|
603 * filesystem queries |
|
604 * |
|
605 * @throws SecurityException |
|
606 * If a required system property value cannot be accessed, or |
|
607 * if a security manager exists and its {@link |
|
608 * java.lang.SecurityManager#checkRead} method denies |
|
609 * read access to the file |
|
610 * |
|
611 * @since 1.1 |
|
612 * @see Path#toRealPath |
|
613 */ |
|
614 public String getCanonicalPath() throws IOException { |
|
615 if (isInvalid()) { |
|
616 throw new IOException("Invalid file path"); |
|
617 } |
|
618 return fs.canonicalize(fs.resolve(this)); |
|
619 } |
|
620 |
|
621 /** |
|
622 * Returns the canonical form of this abstract pathname. Equivalent to |
|
623 * <code>new File(this.{@link #getCanonicalPath})</code>. |
|
624 * |
|
625 * @return The canonical pathname string denoting the same file or |
|
626 * directory as this abstract pathname |
|
627 * |
|
628 * @throws IOException |
|
629 * If an I/O error occurs, which is possible because the |
|
630 * construction of the canonical pathname may require |
|
631 * filesystem queries |
|
632 * |
|
633 * @throws SecurityException |
|
634 * If a required system property value cannot be accessed, or |
|
635 * if a security manager exists and its {@link |
|
636 * java.lang.SecurityManager#checkRead} method denies |
|
637 * read access to the file |
|
638 * |
|
639 * @since 1.2 |
|
640 * @see Path#toRealPath |
|
641 */ |
|
642 public File getCanonicalFile() throws IOException { |
|
643 String canonPath = getCanonicalPath(); |
|
644 return new File(canonPath, fs.prefixLength(canonPath)); |
|
645 } |
|
646 |
|
647 private static String slashify(String path, boolean isDirectory) { |
|
648 String p = path; |
|
649 if (File.separatorChar != '/') |
|
650 p = p.replace(File.separatorChar, '/'); |
|
651 if (!p.startsWith("/")) |
|
652 p = "/" + p; |
|
653 if (!p.endsWith("/") && isDirectory) |
|
654 p = p + "/"; |
|
655 return p; |
|
656 } |
|
657 |
|
658 /** |
|
659 * Converts this abstract pathname into a <code>file:</code> URL. The |
|
660 * exact form of the URL is system-dependent. If it can be determined that |
|
661 * the file denoted by this abstract pathname is a directory, then the |
|
662 * resulting URL will end with a slash. |
|
663 * |
|
664 * @return A URL object representing the equivalent file URL |
|
665 * |
|
666 * @throws MalformedURLException |
|
667 * If the path cannot be parsed as a URL |
|
668 * |
|
669 * @see #toURI() |
|
670 * @see java.net.URI |
|
671 * @see java.net.URI#toURL() |
|
672 * @see java.net.URL |
|
673 * @since 1.2 |
|
674 * |
|
675 * @deprecated This method does not automatically escape characters that |
|
676 * are illegal in URLs. It is recommended that new code convert an |
|
677 * abstract pathname into a URL by first converting it into a URI, via the |
|
678 * {@link #toURI() toURI} method, and then converting the URI into a URL |
|
679 * via the {@link java.net.URI#toURL() URI.toURL} method. |
|
680 */ |
|
681 @Deprecated |
|
682 public URL toURL() throws MalformedURLException { |
|
683 if (isInvalid()) { |
|
684 throw new MalformedURLException("Invalid file path"); |
|
685 } |
|
686 return new URL("file", "", slashify(getAbsolutePath(), isDirectory())); |
|
687 } |
|
688 |
|
689 /** |
|
690 * Constructs a {@code file:} URI that represents this abstract pathname. |
|
691 * |
|
692 * <p> The exact form of the URI is system-dependent. If it can be |
|
693 * determined that the file denoted by this abstract pathname is a |
|
694 * directory, then the resulting URI will end with a slash. |
|
695 * |
|
696 * <p> For a given abstract pathname <i>f</i>, it is guaranteed that |
|
697 * |
|
698 * <blockquote><code> |
|
699 * new {@link #File(java.net.URI) File}(</code><i> f</i><code>.toURI()).equals( |
|
700 * </code><i> f</i><code>.{@link #getAbsoluteFile() getAbsoluteFile}()) |
|
701 * </code></blockquote> |
|
702 * |
|
703 * so long as the original abstract pathname, the URI, and the new abstract |
|
704 * pathname are all created in (possibly different invocations of) the same |
|
705 * Java virtual machine. Due to the system-dependent nature of abstract |
|
706 * pathnames, however, this relationship typically does not hold when a |
|
707 * {@code file:} URI that is created in a virtual machine on one operating |
|
708 * system is converted into an abstract pathname in a virtual machine on a |
|
709 * different operating system. |
|
710 * |
|
711 * <p> Note that when this abstract pathname represents a UNC pathname then |
|
712 * all components of the UNC (including the server name component) are encoded |
|
713 * in the {@code URI} path. The authority component is undefined, meaning |
|
714 * that it is represented as {@code null}. The {@link Path} class defines the |
|
715 * {@link Path#toUri toUri} method to encode the server name in the authority |
|
716 * component of the resulting {@code URI}. The {@link #toPath toPath} method |
|
717 * may be used to obtain a {@code Path} representing this abstract pathname. |
|
718 * |
|
719 * @return An absolute, hierarchical URI with a scheme equal to |
|
720 * {@code "file"}, a path representing this abstract pathname, |
|
721 * and undefined authority, query, and fragment components |
|
722 * @throws SecurityException If a required system property value cannot |
|
723 * be accessed. |
|
724 * |
|
725 * @see #File(java.net.URI) |
|
726 * @see java.net.URI |
|
727 * @see java.net.URI#toURL() |
|
728 * @since 1.4 |
|
729 */ |
|
730 public URI toURI() { |
|
731 try { |
|
732 File f = getAbsoluteFile(); |
|
733 String sp = slashify(f.getPath(), f.isDirectory()); |
|
734 if (sp.startsWith("//")) |
|
735 sp = "//" + sp; |
|
736 return new URI("file", null, sp, null); |
|
737 } catch (URISyntaxException x) { |
|
738 throw new Error(x); // Can't happen |
|
739 } |
|
740 } |
|
741 |
|
742 |
|
743 /* -- Attribute accessors -- */ |
|
744 |
|
745 /** |
|
746 * Tests whether the application can read the file denoted by this |
|
747 * abstract pathname. On some platforms it may be possible to start the |
|
748 * Java virtual machine with special privileges that allow it to read |
|
749 * files that are marked as unreadable. Consequently this method may return |
|
750 * {@code true} even though the file does not have read permissions. |
|
751 * |
|
752 * @return <code>true</code> if and only if the file specified by this |
|
753 * abstract pathname exists <em>and</em> can be read by the |
|
754 * application; <code>false</code> otherwise |
|
755 * |
|
756 * @throws SecurityException |
|
757 * If a security manager exists and its {@link |
|
758 * java.lang.SecurityManager#checkRead(java.lang.String)} |
|
759 * method denies read access to the file |
|
760 */ |
|
761 public boolean canRead() { |
|
762 SecurityManager security = System.getSecurityManager(); |
|
763 if (security != null) { |
|
764 security.checkRead(path); |
|
765 } |
|
766 if (isInvalid()) { |
|
767 return false; |
|
768 } |
|
769 return fs.checkAccess(this, FileSystem.ACCESS_READ); |
|
770 } |
|
771 |
|
772 /** |
|
773 * Tests whether the application can modify the file denoted by this |
|
774 * abstract pathname. On some platforms it may be possible to start the |
|
775 * Java virtual machine with special privileges that allow it to modify |
|
776 * files that are marked read-only. Consequently this method may return |
|
777 * {@code true} even though the file is marked read-only. |
|
778 * |
|
779 * @return <code>true</code> if and only if the file system actually |
|
780 * contains a file denoted by this abstract pathname <em>and</em> |
|
781 * the application is allowed to write to the file; |
|
782 * <code>false</code> otherwise. |
|
783 * |
|
784 * @throws SecurityException |
|
785 * If a security manager exists and its {@link |
|
786 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
787 * method denies write access to the file |
|
788 */ |
|
789 public boolean canWrite() { |
|
790 SecurityManager security = System.getSecurityManager(); |
|
791 if (security != null) { |
|
792 security.checkWrite(path); |
|
793 } |
|
794 if (isInvalid()) { |
|
795 return false; |
|
796 } |
|
797 return fs.checkAccess(this, FileSystem.ACCESS_WRITE); |
|
798 } |
|
799 |
|
800 /** |
|
801 * Tests whether the file or directory denoted by this abstract pathname |
|
802 * exists. |
|
803 * |
|
804 * @return <code>true</code> if and only if the file or directory denoted |
|
805 * by this abstract pathname exists; <code>false</code> otherwise |
|
806 * |
|
807 * @throws SecurityException |
|
808 * If a security manager exists and its {@link |
|
809 * java.lang.SecurityManager#checkRead(java.lang.String)} |
|
810 * method denies read access to the file or directory |
|
811 */ |
|
812 public boolean exists() { |
|
813 SecurityManager security = System.getSecurityManager(); |
|
814 if (security != null) { |
|
815 security.checkRead(path); |
|
816 } |
|
817 if (isInvalid()) { |
|
818 return false; |
|
819 } |
|
820 return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0); |
|
821 } |
|
822 |
|
823 /** |
|
824 * Tests whether the file denoted by this abstract pathname is a |
|
825 * directory. |
|
826 * |
|
827 * <p> Where it is required to distinguish an I/O exception from the case |
|
828 * that the file is not a directory, or where several attributes of the |
|
829 * same file are required at the same time, then the {@link |
|
830 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[]) |
|
831 * Files.readAttributes} method may be used. |
|
832 * |
|
833 * @return <code>true</code> if and only if the file denoted by this |
|
834 * abstract pathname exists <em>and</em> is a directory; |
|
835 * <code>false</code> otherwise |
|
836 * |
|
837 * @throws SecurityException |
|
838 * If a security manager exists and its {@link |
|
839 * java.lang.SecurityManager#checkRead(java.lang.String)} |
|
840 * method denies read access to the file |
|
841 */ |
|
842 public boolean isDirectory() { |
|
843 SecurityManager security = System.getSecurityManager(); |
|
844 if (security != null) { |
|
845 security.checkRead(path); |
|
846 } |
|
847 if (isInvalid()) { |
|
848 return false; |
|
849 } |
|
850 return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY) |
|
851 != 0); |
|
852 } |
|
853 |
|
854 /** |
|
855 * Tests whether the file denoted by this abstract pathname is a normal |
|
856 * file. A file is <em>normal</em> if it is not a directory and, in |
|
857 * addition, satisfies other system-dependent criteria. Any non-directory |
|
858 * file created by a Java application is guaranteed to be a normal file. |
|
859 * |
|
860 * <p> Where it is required to distinguish an I/O exception from the case |
|
861 * that the file is not a normal file, or where several attributes of the |
|
862 * same file are required at the same time, then the {@link |
|
863 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[]) |
|
864 * Files.readAttributes} method may be used. |
|
865 * |
|
866 * @return <code>true</code> if and only if the file denoted by this |
|
867 * abstract pathname exists <em>and</em> is a normal file; |
|
868 * <code>false</code> otherwise |
|
869 * |
|
870 * @throws SecurityException |
|
871 * If a security manager exists and its {@link |
|
872 * java.lang.SecurityManager#checkRead(java.lang.String)} |
|
873 * method denies read access to the file |
|
874 */ |
|
875 public boolean isFile() { |
|
876 SecurityManager security = System.getSecurityManager(); |
|
877 if (security != null) { |
|
878 security.checkRead(path); |
|
879 } |
|
880 if (isInvalid()) { |
|
881 return false; |
|
882 } |
|
883 return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0); |
|
884 } |
|
885 |
|
886 /** |
|
887 * Tests whether the file named by this abstract pathname is a hidden |
|
888 * file. The exact definition of <em>hidden</em> is system-dependent. On |
|
889 * UNIX systems, a file is considered to be hidden if its name begins with |
|
890 * a period character (<code>'.'</code>). On Microsoft Windows systems, a file is |
|
891 * considered to be hidden if it has been marked as such in the filesystem. |
|
892 * |
|
893 * @return <code>true</code> if and only if the file denoted by this |
|
894 * abstract pathname is hidden according to the conventions of the |
|
895 * underlying platform |
|
896 * |
|
897 * @throws SecurityException |
|
898 * If a security manager exists and its {@link |
|
899 * java.lang.SecurityManager#checkRead(java.lang.String)} |
|
900 * method denies read access to the file |
|
901 * |
|
902 * @since 1.2 |
|
903 */ |
|
904 public boolean isHidden() { |
|
905 SecurityManager security = System.getSecurityManager(); |
|
906 if (security != null) { |
|
907 security.checkRead(path); |
|
908 } |
|
909 if (isInvalid()) { |
|
910 return false; |
|
911 } |
|
912 return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0); |
|
913 } |
|
914 |
|
915 /** |
|
916 * Returns the time that the file denoted by this abstract pathname was |
|
917 * last modified. |
|
918 * |
|
919 * @apiNote |
|
920 * While the unit of time of the return value is milliseconds, the |
|
921 * granularity of the value depends on the underlying file system and may |
|
922 * be larger. For example, some file systems use time stamps in units of |
|
923 * seconds. |
|
924 * |
|
925 * <p> Where it is required to distinguish an I/O exception from the case |
|
926 * where {@code 0L} is returned, or where several attributes of the |
|
927 * same file are required at the same time, or where the time of last |
|
928 * access or the creation time are required, then the {@link |
|
929 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[]) |
|
930 * Files.readAttributes} method may be used. If however only the |
|
931 * time of last modification is required, then the |
|
932 * {@link java.nio.file.Files#getLastModifiedTime(Path,LinkOption[]) |
|
933 * Files.getLastModifiedTime} method may be used instead. |
|
934 * |
|
935 * @return A <code>long</code> value representing the time the file was |
|
936 * last modified, measured in milliseconds since the epoch |
|
937 * (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the |
|
938 * file does not exist or if an I/O error occurs. The value may |
|
939 * be negative indicating the number of milliseconds before the |
|
940 * epoch |
|
941 * |
|
942 * @throws SecurityException |
|
943 * If a security manager exists and its {@link |
|
944 * java.lang.SecurityManager#checkRead(java.lang.String)} |
|
945 * method denies read access to the file |
|
946 */ |
|
947 public long lastModified() { |
|
948 SecurityManager security = System.getSecurityManager(); |
|
949 if (security != null) { |
|
950 security.checkRead(path); |
|
951 } |
|
952 if (isInvalid()) { |
|
953 return 0L; |
|
954 } |
|
955 return fs.getLastModifiedTime(this); |
|
956 } |
|
957 |
|
958 /** |
|
959 * Returns the length of the file denoted by this abstract pathname. |
|
960 * The return value is unspecified if this pathname denotes a directory. |
|
961 * |
|
962 * <p> Where it is required to distinguish an I/O exception from the case |
|
963 * that {@code 0L} is returned, or where several attributes of the same file |
|
964 * are required at the same time, then the {@link |
|
965 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[]) |
|
966 * Files.readAttributes} method may be used. |
|
967 * |
|
968 * @return The length, in bytes, of the file denoted by this abstract |
|
969 * pathname, or <code>0L</code> if the file does not exist. Some |
|
970 * operating systems may return <code>0L</code> for pathnames |
|
971 * denoting system-dependent entities such as devices or pipes. |
|
972 * |
|
973 * @throws SecurityException |
|
974 * If a security manager exists and its {@link |
|
975 * java.lang.SecurityManager#checkRead(java.lang.String)} |
|
976 * method denies read access to the file |
|
977 */ |
|
978 public long length() { |
|
979 SecurityManager security = System.getSecurityManager(); |
|
980 if (security != null) { |
|
981 security.checkRead(path); |
|
982 } |
|
983 if (isInvalid()) { |
|
984 return 0L; |
|
985 } |
|
986 return fs.getLength(this); |
|
987 } |
|
988 |
|
989 |
|
990 /* -- File operations -- */ |
|
991 |
|
992 /** |
|
993 * Atomically creates a new, empty file named by this abstract pathname if |
|
994 * and only if a file with this name does not yet exist. The check for the |
|
995 * existence of the file and the creation of the file if it does not exist |
|
996 * are a single operation that is atomic with respect to all other |
|
997 * filesystem activities that might affect the file. |
|
998 * <P> |
|
999 * Note: this method should <i>not</i> be used for file-locking, as |
|
1000 * the resulting protocol cannot be made to work reliably. The |
|
1001 * {@link java.nio.channels.FileLock FileLock} |
|
1002 * facility should be used instead. |
|
1003 * |
|
1004 * @return <code>true</code> if the named file does not exist and was |
|
1005 * successfully created; <code>false</code> if the named file |
|
1006 * already exists |
|
1007 * |
|
1008 * @throws IOException |
|
1009 * If an I/O error occurred |
|
1010 * |
|
1011 * @throws SecurityException |
|
1012 * If a security manager exists and its {@link |
|
1013 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1014 * method denies write access to the file |
|
1015 * |
|
1016 * @since 1.2 |
|
1017 */ |
|
1018 public boolean createNewFile() throws IOException { |
|
1019 SecurityManager security = System.getSecurityManager(); |
|
1020 if (security != null) security.checkWrite(path); |
|
1021 if (isInvalid()) { |
|
1022 throw new IOException("Invalid file path"); |
|
1023 } |
|
1024 return fs.createFileExclusively(path); |
|
1025 } |
|
1026 |
|
1027 /** |
|
1028 * Deletes the file or directory denoted by this abstract pathname. If |
|
1029 * this pathname denotes a directory, then the directory must be empty in |
|
1030 * order to be deleted. |
|
1031 * |
|
1032 * <p> Note that the {@link java.nio.file.Files} class defines the {@link |
|
1033 * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException} |
|
1034 * when a file cannot be deleted. This is useful for error reporting and to |
|
1035 * diagnose why a file cannot be deleted. |
|
1036 * |
|
1037 * @return <code>true</code> if and only if the file or directory is |
|
1038 * successfully deleted; <code>false</code> otherwise |
|
1039 * |
|
1040 * @throws SecurityException |
|
1041 * If a security manager exists and its {@link |
|
1042 * java.lang.SecurityManager#checkDelete} method denies |
|
1043 * delete access to the file |
|
1044 */ |
|
1045 public boolean delete() { |
|
1046 SecurityManager security = System.getSecurityManager(); |
|
1047 if (security != null) { |
|
1048 security.checkDelete(path); |
|
1049 } |
|
1050 if (isInvalid()) { |
|
1051 return false; |
|
1052 } |
|
1053 return fs.delete(this); |
|
1054 } |
|
1055 |
|
1056 /** |
|
1057 * Requests that the file or directory denoted by this abstract |
|
1058 * pathname be deleted when the virtual machine terminates. |
|
1059 * Files (or directories) are deleted in the reverse order that |
|
1060 * they are registered. Invoking this method to delete a file or |
|
1061 * directory that is already registered for deletion has no effect. |
|
1062 * Deletion will be attempted only for normal termination of the |
|
1063 * virtual machine, as defined by the Java Language Specification. |
|
1064 * |
|
1065 * <p> Once deletion has been requested, it is not possible to cancel the |
|
1066 * request. This method should therefore be used with care. |
|
1067 * |
|
1068 * <P> |
|
1069 * Note: this method should <i>not</i> be used for file-locking, as |
|
1070 * the resulting protocol cannot be made to work reliably. The |
|
1071 * {@link java.nio.channels.FileLock FileLock} |
|
1072 * facility should be used instead. |
|
1073 * |
|
1074 * @throws SecurityException |
|
1075 * If a security manager exists and its {@link |
|
1076 * java.lang.SecurityManager#checkDelete} method denies |
|
1077 * delete access to the file |
|
1078 * |
|
1079 * @see #delete |
|
1080 * |
|
1081 * @since 1.2 |
|
1082 */ |
|
1083 public void deleteOnExit() { |
|
1084 SecurityManager security = System.getSecurityManager(); |
|
1085 if (security != null) { |
|
1086 security.checkDelete(path); |
|
1087 } |
|
1088 if (isInvalid()) { |
|
1089 return; |
|
1090 } |
|
1091 DeleteOnExitHook.add(path); |
|
1092 } |
|
1093 |
|
1094 /** |
|
1095 * Returns an array of strings naming the files and directories in the |
|
1096 * directory denoted by this abstract pathname. |
|
1097 * |
|
1098 * <p> If this abstract pathname does not denote a directory, then this |
|
1099 * method returns {@code null}. Otherwise an array of strings is |
|
1100 * returned, one for each file or directory in the directory. Names |
|
1101 * denoting the directory itself and the directory's parent directory are |
|
1102 * not included in the result. Each string is a file name rather than a |
|
1103 * complete path. |
|
1104 * |
|
1105 * <p> There is no guarantee that the name strings in the resulting array |
|
1106 * will appear in any specific order; they are not, in particular, |
|
1107 * guaranteed to appear in alphabetical order. |
|
1108 * |
|
1109 * <p> Note that the {@link java.nio.file.Files} class defines the {@link |
|
1110 * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to |
|
1111 * open a directory and iterate over the names of the files in the directory. |
|
1112 * This may use less resources when working with very large directories, and |
|
1113 * may be more responsive when working with remote directories. |
|
1114 * |
|
1115 * @return An array of strings naming the files and directories in the |
|
1116 * directory denoted by this abstract pathname. The array will be |
|
1117 * empty if the directory is empty. Returns {@code null} if |
|
1118 * this abstract pathname does not denote a directory, or if an |
|
1119 * I/O error occurs. |
|
1120 * |
|
1121 * @throws SecurityException |
|
1122 * If a security manager exists and its {@link |
|
1123 * SecurityManager#checkRead(String)} method denies read access to |
|
1124 * the directory |
|
1125 */ |
|
1126 public String[] list() { |
|
1127 SecurityManager security = System.getSecurityManager(); |
|
1128 if (security != null) { |
|
1129 security.checkRead(path); |
|
1130 } |
|
1131 if (isInvalid()) { |
|
1132 return null; |
|
1133 } |
|
1134 return fs.list(this); |
|
1135 } |
|
1136 |
|
1137 /** |
|
1138 * Returns an array of strings naming the files and directories in the |
|
1139 * directory denoted by this abstract pathname that satisfy the specified |
|
1140 * filter. The behavior of this method is the same as that of the |
|
1141 * {@link #list()} method, except that the strings in the returned array |
|
1142 * must satisfy the filter. If the given {@code filter} is {@code null} |
|
1143 * then all names are accepted. Otherwise, a name satisfies the filter if |
|
1144 * and only if the value {@code true} results when the {@link |
|
1145 * FilenameFilter#accept FilenameFilter.accept(File, String)} method |
|
1146 * of the filter is invoked on this abstract pathname and the name of a |
|
1147 * file or directory in the directory that it denotes. |
|
1148 * |
|
1149 * @param filter |
|
1150 * A filename filter |
|
1151 * |
|
1152 * @return An array of strings naming the files and directories in the |
|
1153 * directory denoted by this abstract pathname that were accepted |
|
1154 * by the given {@code filter}. The array will be empty if the |
|
1155 * directory is empty or if no names were accepted by the filter. |
|
1156 * Returns {@code null} if this abstract pathname does not denote |
|
1157 * a directory, or if an I/O error occurs. |
|
1158 * |
|
1159 * @throws SecurityException |
|
1160 * If a security manager exists and its {@link |
|
1161 * SecurityManager#checkRead(String)} method denies read access to |
|
1162 * the directory |
|
1163 * |
|
1164 * @see java.nio.file.Files#newDirectoryStream(Path,String) |
|
1165 */ |
|
1166 public String[] list(FilenameFilter filter) { |
|
1167 String names[] = list(); |
|
1168 if ((names == null) || (filter == null)) { |
|
1169 return names; |
|
1170 } |
|
1171 List<String> v = new ArrayList<>(); |
|
1172 for (int i = 0 ; i < names.length ; i++) { |
|
1173 if (filter.accept(this, names[i])) { |
|
1174 v.add(names[i]); |
|
1175 } |
|
1176 } |
|
1177 return v.toArray(new String[v.size()]); |
|
1178 } |
|
1179 |
|
1180 /** |
|
1181 * Returns an array of abstract pathnames denoting the files in the |
|
1182 * directory denoted by this abstract pathname. |
|
1183 * |
|
1184 * <p> If this abstract pathname does not denote a directory, then this |
|
1185 * method returns {@code null}. Otherwise an array of {@code File} objects |
|
1186 * is returned, one for each file or directory in the directory. Pathnames |
|
1187 * denoting the directory itself and the directory's parent directory are |
|
1188 * not included in the result. Each resulting abstract pathname is |
|
1189 * constructed from this abstract pathname using the {@link #File(File, |
|
1190 * String) File(File, String)} constructor. Therefore if this |
|
1191 * pathname is absolute then each resulting pathname is absolute; if this |
|
1192 * pathname is relative then each resulting pathname will be relative to |
|
1193 * the same directory. |
|
1194 * |
|
1195 * <p> There is no guarantee that the name strings in the resulting array |
|
1196 * will appear in any specific order; they are not, in particular, |
|
1197 * guaranteed to appear in alphabetical order. |
|
1198 * |
|
1199 * <p> Note that the {@link java.nio.file.Files} class defines the {@link |
|
1200 * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method |
|
1201 * to open a directory and iterate over the names of the files in the |
|
1202 * directory. This may use less resources when working with very large |
|
1203 * directories. |
|
1204 * |
|
1205 * @return An array of abstract pathnames denoting the files and |
|
1206 * directories in the directory denoted by this abstract pathname. |
|
1207 * The array will be empty if the directory is empty. Returns |
|
1208 * {@code null} if this abstract pathname does not denote a |
|
1209 * directory, or if an I/O error occurs. |
|
1210 * |
|
1211 * @throws SecurityException |
|
1212 * If a security manager exists and its {@link |
|
1213 * SecurityManager#checkRead(String)} method denies read access to |
|
1214 * the directory |
|
1215 * |
|
1216 * @since 1.2 |
|
1217 */ |
|
1218 public File[] listFiles() { |
|
1219 String[] ss = list(); |
|
1220 if (ss == null) return null; |
|
1221 int n = ss.length; |
|
1222 File[] fs = new File[n]; |
|
1223 for (int i = 0; i < n; i++) { |
|
1224 fs[i] = new File(ss[i], this); |
|
1225 } |
|
1226 return fs; |
|
1227 } |
|
1228 |
|
1229 /** |
|
1230 * Returns an array of abstract pathnames denoting the files and |
|
1231 * directories in the directory denoted by this abstract pathname that |
|
1232 * satisfy the specified filter. The behavior of this method is the same |
|
1233 * as that of the {@link #listFiles()} method, except that the pathnames in |
|
1234 * the returned array must satisfy the filter. If the given {@code filter} |
|
1235 * is {@code null} then all pathnames are accepted. Otherwise, a pathname |
|
1236 * satisfies the filter if and only if the value {@code true} results when |
|
1237 * the {@link FilenameFilter#accept |
|
1238 * FilenameFilter.accept(File, String)} method of the filter is |
|
1239 * invoked on this abstract pathname and the name of a file or directory in |
|
1240 * the directory that it denotes. |
|
1241 * |
|
1242 * @param filter |
|
1243 * A filename filter |
|
1244 * |
|
1245 * @return An array of abstract pathnames denoting the files and |
|
1246 * directories in the directory denoted by this abstract pathname. |
|
1247 * The array will be empty if the directory is empty. Returns |
|
1248 * {@code null} if this abstract pathname does not denote a |
|
1249 * directory, or if an I/O error occurs. |
|
1250 * |
|
1251 * @throws SecurityException |
|
1252 * If a security manager exists and its {@link |
|
1253 * SecurityManager#checkRead(String)} method denies read access to |
|
1254 * the directory |
|
1255 * |
|
1256 * @since 1.2 |
|
1257 * @see java.nio.file.Files#newDirectoryStream(Path,String) |
|
1258 */ |
|
1259 public File[] listFiles(FilenameFilter filter) { |
|
1260 String ss[] = list(); |
|
1261 if (ss == null) return null; |
|
1262 ArrayList<File> files = new ArrayList<>(); |
|
1263 for (String s : ss) |
|
1264 if ((filter == null) || filter.accept(this, s)) |
|
1265 files.add(new File(s, this)); |
|
1266 return files.toArray(new File[files.size()]); |
|
1267 } |
|
1268 |
|
1269 /** |
|
1270 * Returns an array of abstract pathnames denoting the files and |
|
1271 * directories in the directory denoted by this abstract pathname that |
|
1272 * satisfy the specified filter. The behavior of this method is the same |
|
1273 * as that of the {@link #listFiles()} method, except that the pathnames in |
|
1274 * the returned array must satisfy the filter. If the given {@code filter} |
|
1275 * is {@code null} then all pathnames are accepted. Otherwise, a pathname |
|
1276 * satisfies the filter if and only if the value {@code true} results when |
|
1277 * the {@link FileFilter#accept FileFilter.accept(File)} method of the |
|
1278 * filter is invoked on the pathname. |
|
1279 * |
|
1280 * @param filter |
|
1281 * A file filter |
|
1282 * |
|
1283 * @return An array of abstract pathnames denoting the files and |
|
1284 * directories in the directory denoted by this abstract pathname. |
|
1285 * The array will be empty if the directory is empty. Returns |
|
1286 * {@code null} if this abstract pathname does not denote a |
|
1287 * directory, or if an I/O error occurs. |
|
1288 * |
|
1289 * @throws SecurityException |
|
1290 * If a security manager exists and its {@link |
|
1291 * SecurityManager#checkRead(String)} method denies read access to |
|
1292 * the directory |
|
1293 * |
|
1294 * @since 1.2 |
|
1295 * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter) |
|
1296 */ |
|
1297 public File[] listFiles(FileFilter filter) { |
|
1298 String ss[] = list(); |
|
1299 if (ss == null) return null; |
|
1300 ArrayList<File> files = new ArrayList<>(); |
|
1301 for (String s : ss) { |
|
1302 File f = new File(s, this); |
|
1303 if ((filter == null) || filter.accept(f)) |
|
1304 files.add(f); |
|
1305 } |
|
1306 return files.toArray(new File[files.size()]); |
|
1307 } |
|
1308 |
|
1309 /** |
|
1310 * Creates the directory named by this abstract pathname. |
|
1311 * |
|
1312 * @return <code>true</code> if and only if the directory was |
|
1313 * created; <code>false</code> otherwise |
|
1314 * |
|
1315 * @throws SecurityException |
|
1316 * If a security manager exists and its {@link |
|
1317 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1318 * method does not permit the named directory to be created |
|
1319 */ |
|
1320 public boolean mkdir() { |
|
1321 SecurityManager security = System.getSecurityManager(); |
|
1322 if (security != null) { |
|
1323 security.checkWrite(path); |
|
1324 } |
|
1325 if (isInvalid()) { |
|
1326 return false; |
|
1327 } |
|
1328 return fs.createDirectory(this); |
|
1329 } |
|
1330 |
|
1331 /** |
|
1332 * Creates the directory named by this abstract pathname, including any |
|
1333 * necessary but nonexistent parent directories. Note that if this |
|
1334 * operation fails it may have succeeded in creating some of the necessary |
|
1335 * parent directories. |
|
1336 * |
|
1337 * @return <code>true</code> if and only if the directory was created, |
|
1338 * along with all necessary parent directories; <code>false</code> |
|
1339 * otherwise |
|
1340 * |
|
1341 * @throws SecurityException |
|
1342 * If a security manager exists and its {@link |
|
1343 * java.lang.SecurityManager#checkRead(java.lang.String)} |
|
1344 * method does not permit verification of the existence of the |
|
1345 * named directory and all necessary parent directories; or if |
|
1346 * the {@link |
|
1347 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1348 * method does not permit the named directory and all necessary |
|
1349 * parent directories to be created |
|
1350 */ |
|
1351 public boolean mkdirs() { |
|
1352 if (exists()) { |
|
1353 return false; |
|
1354 } |
|
1355 if (mkdir()) { |
|
1356 return true; |
|
1357 } |
|
1358 File canonFile = null; |
|
1359 try { |
|
1360 canonFile = getCanonicalFile(); |
|
1361 } catch (IOException e) { |
|
1362 return false; |
|
1363 } |
|
1364 |
|
1365 File parent = canonFile.getParentFile(); |
|
1366 return (parent != null && (parent.mkdirs() || parent.exists()) && |
|
1367 canonFile.mkdir()); |
|
1368 } |
|
1369 |
|
1370 /** |
|
1371 * Renames the file denoted by this abstract pathname. |
|
1372 * |
|
1373 * <p> Many aspects of the behavior of this method are inherently |
|
1374 * platform-dependent: The rename operation might not be able to move a |
|
1375 * file from one filesystem to another, it might not be atomic, and it |
|
1376 * might not succeed if a file with the destination abstract pathname |
|
1377 * already exists. The return value should always be checked to make sure |
|
1378 * that the rename operation was successful. |
|
1379 * |
|
1380 * <p> Note that the {@link java.nio.file.Files} class defines the {@link |
|
1381 * java.nio.file.Files#move move} method to move or rename a file in a |
|
1382 * platform independent manner. |
|
1383 * |
|
1384 * @param dest The new abstract pathname for the named file |
|
1385 * |
|
1386 * @return <code>true</code> if and only if the renaming succeeded; |
|
1387 * <code>false</code> otherwise |
|
1388 * |
|
1389 * @throws SecurityException |
|
1390 * If a security manager exists and its {@link |
|
1391 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1392 * method denies write access to either the old or new pathnames |
|
1393 * |
|
1394 * @throws NullPointerException |
|
1395 * If parameter <code>dest</code> is <code>null</code> |
|
1396 */ |
|
1397 public boolean renameTo(File dest) { |
|
1398 SecurityManager security = System.getSecurityManager(); |
|
1399 if (security != null) { |
|
1400 security.checkWrite(path); |
|
1401 security.checkWrite(dest.path); |
|
1402 } |
|
1403 if (dest == null) { |
|
1404 throw new NullPointerException(); |
|
1405 } |
|
1406 if (this.isInvalid() || dest.isInvalid()) { |
|
1407 return false; |
|
1408 } |
|
1409 return fs.rename(this, dest); |
|
1410 } |
|
1411 |
|
1412 /** |
|
1413 * Sets the last-modified time of the file or directory named by this |
|
1414 * abstract pathname. |
|
1415 * |
|
1416 * <p> All platforms support file-modification times to the nearest second, |
|
1417 * but some provide more precision. The argument will be truncated to fit |
|
1418 * the supported precision. If the operation succeeds and no intervening |
|
1419 * operations on the file take place, then the next invocation of the |
|
1420 * {@link #lastModified} method will return the (possibly |
|
1421 * truncated) <code>time</code> argument that was passed to this method. |
|
1422 * |
|
1423 * @param time The new last-modified time, measured in milliseconds since |
|
1424 * the epoch (00:00:00 GMT, January 1, 1970) |
|
1425 * |
|
1426 * @return <code>true</code> if and only if the operation succeeded; |
|
1427 * <code>false</code> otherwise |
|
1428 * |
|
1429 * @throws IllegalArgumentException If the argument is negative |
|
1430 * |
|
1431 * @throws SecurityException |
|
1432 * If a security manager exists and its {@link |
|
1433 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1434 * method denies write access to the named file |
|
1435 * |
|
1436 * @since 1.2 |
|
1437 */ |
|
1438 public boolean setLastModified(long time) { |
|
1439 if (time < 0) throw new IllegalArgumentException("Negative time"); |
|
1440 SecurityManager security = System.getSecurityManager(); |
|
1441 if (security != null) { |
|
1442 security.checkWrite(path); |
|
1443 } |
|
1444 if (isInvalid()) { |
|
1445 return false; |
|
1446 } |
|
1447 return fs.setLastModifiedTime(this, time); |
|
1448 } |
|
1449 |
|
1450 /** |
|
1451 * Marks the file or directory named by this abstract pathname so that |
|
1452 * only read operations are allowed. After invoking this method the file |
|
1453 * or directory will not change until it is either deleted or marked |
|
1454 * to allow write access. On some platforms it may be possible to start the |
|
1455 * Java virtual machine with special privileges that allow it to modify |
|
1456 * files that are marked read-only. Whether or not a read-only file or |
|
1457 * directory may be deleted depends upon the underlying system. |
|
1458 * |
|
1459 * @return <code>true</code> if and only if the operation succeeded; |
|
1460 * <code>false</code> otherwise |
|
1461 * |
|
1462 * @throws SecurityException |
|
1463 * If a security manager exists and its {@link |
|
1464 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1465 * method denies write access to the named file |
|
1466 * |
|
1467 * @since 1.2 |
|
1468 */ |
|
1469 public boolean setReadOnly() { |
|
1470 SecurityManager security = System.getSecurityManager(); |
|
1471 if (security != null) { |
|
1472 security.checkWrite(path); |
|
1473 } |
|
1474 if (isInvalid()) { |
|
1475 return false; |
|
1476 } |
|
1477 return fs.setReadOnly(this); |
|
1478 } |
|
1479 |
|
1480 /** |
|
1481 * Sets the owner's or everybody's write permission for this abstract |
|
1482 * pathname. On some platforms it may be possible to start the Java virtual |
|
1483 * machine with special privileges that allow it to modify files that |
|
1484 * disallow write operations. |
|
1485 * |
|
1486 * <p> The {@link java.nio.file.Files} class defines methods that operate on |
|
1487 * file attributes including file permissions. This may be used when finer |
|
1488 * manipulation of file permissions is required. |
|
1489 * |
|
1490 * @param writable |
|
1491 * If <code>true</code>, sets the access permission to allow write |
|
1492 * operations; if <code>false</code> to disallow write operations |
|
1493 * |
|
1494 * @param ownerOnly |
|
1495 * If <code>true</code>, the write permission applies only to the |
|
1496 * owner's write permission; otherwise, it applies to everybody. If |
|
1497 * the underlying file system can not distinguish the owner's write |
|
1498 * permission from that of others, then the permission will apply to |
|
1499 * everybody, regardless of this value. |
|
1500 * |
|
1501 * @return <code>true</code> if and only if the operation succeeded. The |
|
1502 * operation will fail if the user does not have permission to change |
|
1503 * the access permissions of this abstract pathname. |
|
1504 * |
|
1505 * @throws SecurityException |
|
1506 * If a security manager exists and its {@link |
|
1507 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1508 * method denies write access to the named file |
|
1509 * |
|
1510 * @since 1.6 |
|
1511 */ |
|
1512 public boolean setWritable(boolean writable, boolean ownerOnly) { |
|
1513 SecurityManager security = System.getSecurityManager(); |
|
1514 if (security != null) { |
|
1515 security.checkWrite(path); |
|
1516 } |
|
1517 if (isInvalid()) { |
|
1518 return false; |
|
1519 } |
|
1520 return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly); |
|
1521 } |
|
1522 |
|
1523 /** |
|
1524 * A convenience method to set the owner's write permission for this abstract |
|
1525 * pathname. On some platforms it may be possible to start the Java virtual |
|
1526 * machine with special privileges that allow it to modify files that |
|
1527 * disallow write operations. |
|
1528 * |
|
1529 * <p> An invocation of this method of the form {@code file.setWritable(arg)} |
|
1530 * behaves in exactly the same way as the invocation |
|
1531 * |
|
1532 * <pre>{@code |
|
1533 * file.setWritable(arg, true) |
|
1534 * }</pre> |
|
1535 * |
|
1536 * @param writable |
|
1537 * If <code>true</code>, sets the access permission to allow write |
|
1538 * operations; if <code>false</code> to disallow write operations |
|
1539 * |
|
1540 * @return <code>true</code> if and only if the operation succeeded. The |
|
1541 * operation will fail if the user does not have permission to |
|
1542 * change the access permissions of this abstract pathname. |
|
1543 * |
|
1544 * @throws SecurityException |
|
1545 * If a security manager exists and its {@link |
|
1546 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1547 * method denies write access to the file |
|
1548 * |
|
1549 * @since 1.6 |
|
1550 */ |
|
1551 public boolean setWritable(boolean writable) { |
|
1552 return setWritable(writable, true); |
|
1553 } |
|
1554 |
|
1555 /** |
|
1556 * Sets the owner's or everybody's read permission for this abstract |
|
1557 * pathname. On some platforms it may be possible to start the Java virtual |
|
1558 * machine with special privileges that allow it to read files that are |
|
1559 * marked as unreadable. |
|
1560 * |
|
1561 * <p> The {@link java.nio.file.Files} class defines methods that operate on |
|
1562 * file attributes including file permissions. This may be used when finer |
|
1563 * manipulation of file permissions is required. |
|
1564 * |
|
1565 * @param readable |
|
1566 * If <code>true</code>, sets the access permission to allow read |
|
1567 * operations; if <code>false</code> to disallow read operations |
|
1568 * |
|
1569 * @param ownerOnly |
|
1570 * If <code>true</code>, the read permission applies only to the |
|
1571 * owner's read permission; otherwise, it applies to everybody. If |
|
1572 * the underlying file system can not distinguish the owner's read |
|
1573 * permission from that of others, then the permission will apply to |
|
1574 * everybody, regardless of this value. |
|
1575 * |
|
1576 * @return <code>true</code> if and only if the operation succeeded. The |
|
1577 * operation will fail if the user does not have permission to |
|
1578 * change the access permissions of this abstract pathname. If |
|
1579 * <code>readable</code> is <code>false</code> and the underlying |
|
1580 * file system does not implement a read permission, then the |
|
1581 * operation will fail. |
|
1582 * |
|
1583 * @throws SecurityException |
|
1584 * If a security manager exists and its {@link |
|
1585 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1586 * method denies write access to the file |
|
1587 * |
|
1588 * @since 1.6 |
|
1589 */ |
|
1590 public boolean setReadable(boolean readable, boolean ownerOnly) { |
|
1591 SecurityManager security = System.getSecurityManager(); |
|
1592 if (security != null) { |
|
1593 security.checkWrite(path); |
|
1594 } |
|
1595 if (isInvalid()) { |
|
1596 return false; |
|
1597 } |
|
1598 return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly); |
|
1599 } |
|
1600 |
|
1601 /** |
|
1602 * A convenience method to set the owner's read permission for this abstract |
|
1603 * pathname. On some platforms it may be possible to start the Java virtual |
|
1604 * machine with special privileges that allow it to read files that are |
|
1605 * marked as unreadable. |
|
1606 * |
|
1607 * <p>An invocation of this method of the form {@code file.setReadable(arg)} |
|
1608 * behaves in exactly the same way as the invocation |
|
1609 * |
|
1610 * <pre>{@code |
|
1611 * file.setReadable(arg, true) |
|
1612 * }</pre> |
|
1613 * |
|
1614 * @param readable |
|
1615 * If <code>true</code>, sets the access permission to allow read |
|
1616 * operations; if <code>false</code> to disallow read operations |
|
1617 * |
|
1618 * @return <code>true</code> if and only if the operation succeeded. The |
|
1619 * operation will fail if the user does not have permission to |
|
1620 * change the access permissions of this abstract pathname. If |
|
1621 * <code>readable</code> is <code>false</code> and the underlying |
|
1622 * file system does not implement a read permission, then the |
|
1623 * operation will fail. |
|
1624 * |
|
1625 * @throws SecurityException |
|
1626 * If a security manager exists and its {@link |
|
1627 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1628 * method denies write access to the file |
|
1629 * |
|
1630 * @since 1.6 |
|
1631 */ |
|
1632 public boolean setReadable(boolean readable) { |
|
1633 return setReadable(readable, true); |
|
1634 } |
|
1635 |
|
1636 /** |
|
1637 * Sets the owner's or everybody's execute permission for this abstract |
|
1638 * pathname. On some platforms it may be possible to start the Java virtual |
|
1639 * machine with special privileges that allow it to execute files that are |
|
1640 * not marked executable. |
|
1641 * |
|
1642 * <p> The {@link java.nio.file.Files} class defines methods that operate on |
|
1643 * file attributes including file permissions. This may be used when finer |
|
1644 * manipulation of file permissions is required. |
|
1645 * |
|
1646 * @param executable |
|
1647 * If <code>true</code>, sets the access permission to allow execute |
|
1648 * operations; if <code>false</code> to disallow execute operations |
|
1649 * |
|
1650 * @param ownerOnly |
|
1651 * If <code>true</code>, the execute permission applies only to the |
|
1652 * owner's execute permission; otherwise, it applies to everybody. |
|
1653 * If the underlying file system can not distinguish the owner's |
|
1654 * execute permission from that of others, then the permission will |
|
1655 * apply to everybody, regardless of this value. |
|
1656 * |
|
1657 * @return <code>true</code> if and only if the operation succeeded. The |
|
1658 * operation will fail if the user does not have permission to |
|
1659 * change the access permissions of this abstract pathname. If |
|
1660 * <code>executable</code> is <code>false</code> and the underlying |
|
1661 * file system does not implement an execute permission, then the |
|
1662 * operation will fail. |
|
1663 * |
|
1664 * @throws SecurityException |
|
1665 * If a security manager exists and its {@link |
|
1666 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1667 * method denies write access to the file |
|
1668 * |
|
1669 * @since 1.6 |
|
1670 */ |
|
1671 public boolean setExecutable(boolean executable, boolean ownerOnly) { |
|
1672 SecurityManager security = System.getSecurityManager(); |
|
1673 if (security != null) { |
|
1674 security.checkWrite(path); |
|
1675 } |
|
1676 if (isInvalid()) { |
|
1677 return false; |
|
1678 } |
|
1679 return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly); |
|
1680 } |
|
1681 |
|
1682 /** |
|
1683 * A convenience method to set the owner's execute permission for this |
|
1684 * abstract pathname. On some platforms it may be possible to start the Java |
|
1685 * virtual machine with special privileges that allow it to execute files |
|
1686 * that are not marked executable. |
|
1687 * |
|
1688 * <p>An invocation of this method of the form {@code file.setExcutable(arg)} |
|
1689 * behaves in exactly the same way as the invocation |
|
1690 * |
|
1691 * <pre>{@code |
|
1692 * file.setExecutable(arg, true) |
|
1693 * }</pre> |
|
1694 * |
|
1695 * @param executable |
|
1696 * If <code>true</code>, sets the access permission to allow execute |
|
1697 * operations; if <code>false</code> to disallow execute operations |
|
1698 * |
|
1699 * @return <code>true</code> if and only if the operation succeeded. The |
|
1700 * operation will fail if the user does not have permission to |
|
1701 * change the access permissions of this abstract pathname. If |
|
1702 * <code>executable</code> is <code>false</code> and the underlying |
|
1703 * file system does not implement an execute permission, then the |
|
1704 * operation will fail. |
|
1705 * |
|
1706 * @throws SecurityException |
|
1707 * If a security manager exists and its {@link |
|
1708 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
1709 * method denies write access to the file |
|
1710 * |
|
1711 * @since 1.6 |
|
1712 */ |
|
1713 public boolean setExecutable(boolean executable) { |
|
1714 return setExecutable(executable, true); |
|
1715 } |
|
1716 |
|
1717 /** |
|
1718 * Tests whether the application can execute the file denoted by this |
|
1719 * abstract pathname. On some platforms it may be possible to start the |
|
1720 * Java virtual machine with special privileges that allow it to execute |
|
1721 * files that are not marked executable. Consequently this method may return |
|
1722 * {@code true} even though the file does not have execute permissions. |
|
1723 * |
|
1724 * @return <code>true</code> if and only if the abstract pathname exists |
|
1725 * <em>and</em> the application is allowed to execute the file |
|
1726 * |
|
1727 * @throws SecurityException |
|
1728 * If a security manager exists and its {@link |
|
1729 * java.lang.SecurityManager#checkExec(java.lang.String)} |
|
1730 * method denies execute access to the file |
|
1731 * |
|
1732 * @since 1.6 |
|
1733 */ |
|
1734 public boolean canExecute() { |
|
1735 SecurityManager security = System.getSecurityManager(); |
|
1736 if (security != null) { |
|
1737 security.checkExec(path); |
|
1738 } |
|
1739 if (isInvalid()) { |
|
1740 return false; |
|
1741 } |
|
1742 return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE); |
|
1743 } |
|
1744 |
|
1745 |
|
1746 /* -- Filesystem interface -- */ |
|
1747 |
|
1748 /** |
|
1749 * List the available filesystem roots. |
|
1750 * |
|
1751 * <p> A particular Java platform may support zero or more |
|
1752 * hierarchically-organized file systems. Each file system has a |
|
1753 * {@code root} directory from which all other files in that file system |
|
1754 * can be reached. Windows platforms, for example, have a root directory |
|
1755 * for each active drive; UNIX platforms have a single root directory, |
|
1756 * namely {@code "/"}. The set of available filesystem roots is affected |
|
1757 * by various system-level operations such as the insertion or ejection of |
|
1758 * removable media and the disconnecting or unmounting of physical or |
|
1759 * virtual disk drives. |
|
1760 * |
|
1761 * <p> This method returns an array of {@code File} objects that denote the |
|
1762 * root directories of the available filesystem roots. It is guaranteed |
|
1763 * that the canonical pathname of any file physically present on the local |
|
1764 * machine will begin with one of the roots returned by this method. |
|
1765 * |
|
1766 * <p> The canonical pathname of a file that resides on some other machine |
|
1767 * and is accessed via a remote-filesystem protocol such as SMB or NFS may |
|
1768 * or may not begin with one of the roots returned by this method. If the |
|
1769 * pathname of a remote file is syntactically indistinguishable from the |
|
1770 * pathname of a local file then it will begin with one of the roots |
|
1771 * returned by this method. Thus, for example, {@code File} objects |
|
1772 * denoting the root directories of the mapped network drives of a Windows |
|
1773 * platform will be returned by this method, while {@code File} objects |
|
1774 * containing UNC pathnames will not be returned by this method. |
|
1775 * |
|
1776 * <p> Unlike most methods in this class, this method does not throw |
|
1777 * security exceptions. If a security manager exists and its {@link |
|
1778 * SecurityManager#checkRead(String)} method denies read access to a |
|
1779 * particular root directory, then that directory will not appear in the |
|
1780 * result. |
|
1781 * |
|
1782 * @return An array of {@code File} objects denoting the available |
|
1783 * filesystem roots, or {@code null} if the set of roots could not |
|
1784 * be determined. The array will be empty if there are no |
|
1785 * filesystem roots. |
|
1786 * |
|
1787 * @since 1.2 |
|
1788 * @see java.nio.file.FileStore |
|
1789 */ |
|
1790 public static File[] listRoots() { |
|
1791 return fs.listRoots(); |
|
1792 } |
|
1793 |
|
1794 |
|
1795 /* -- Disk usage -- */ |
|
1796 |
|
1797 /** |
|
1798 * Returns the size of the partition <a href="#partName">named</a> by this |
|
1799 * abstract pathname. |
|
1800 * |
|
1801 * @return The size, in bytes, of the partition or {@code 0L} if this |
|
1802 * abstract pathname does not name a partition |
|
1803 * |
|
1804 * @throws SecurityException |
|
1805 * If a security manager has been installed and it denies |
|
1806 * {@link RuntimePermission}{@code ("getFileSystemAttributes")} |
|
1807 * or its {@link SecurityManager#checkRead(String)} method denies |
|
1808 * read access to the file named by this abstract pathname |
|
1809 * |
|
1810 * @since 1.6 |
|
1811 */ |
|
1812 public long getTotalSpace() { |
|
1813 SecurityManager sm = System.getSecurityManager(); |
|
1814 if (sm != null) { |
|
1815 sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); |
|
1816 sm.checkRead(path); |
|
1817 } |
|
1818 if (isInvalid()) { |
|
1819 return 0L; |
|
1820 } |
|
1821 return fs.getSpace(this, FileSystem.SPACE_TOTAL); |
|
1822 } |
|
1823 |
|
1824 /** |
|
1825 * Returns the number of unallocated bytes in the partition <a |
|
1826 * href="#partName">named</a> by this abstract path name. |
|
1827 * |
|
1828 * <p> The returned number of unallocated bytes is a hint, but not |
|
1829 * a guarantee, that it is possible to use most or any of these |
|
1830 * bytes. The number of unallocated bytes is most likely to be |
|
1831 * accurate immediately after this call. It is likely to be made |
|
1832 * inaccurate by any external I/O operations including those made |
|
1833 * on the system outside of this virtual machine. This method |
|
1834 * makes no guarantee that write operations to this file system |
|
1835 * will succeed. |
|
1836 * |
|
1837 * @return The number of unallocated bytes on the partition or {@code 0L} |
|
1838 * if the abstract pathname does not name a partition. This |
|
1839 * value will be less than or equal to the total file system size |
|
1840 * returned by {@link #getTotalSpace}. |
|
1841 * |
|
1842 * @throws SecurityException |
|
1843 * If a security manager has been installed and it denies |
|
1844 * {@link RuntimePermission}{@code ("getFileSystemAttributes")} |
|
1845 * or its {@link SecurityManager#checkRead(String)} method denies |
|
1846 * read access to the file named by this abstract pathname |
|
1847 * |
|
1848 * @since 1.6 |
|
1849 */ |
|
1850 public long getFreeSpace() { |
|
1851 SecurityManager sm = System.getSecurityManager(); |
|
1852 if (sm != null) { |
|
1853 sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); |
|
1854 sm.checkRead(path); |
|
1855 } |
|
1856 if (isInvalid()) { |
|
1857 return 0L; |
|
1858 } |
|
1859 return fs.getSpace(this, FileSystem.SPACE_FREE); |
|
1860 } |
|
1861 |
|
1862 /** |
|
1863 * Returns the number of bytes available to this virtual machine on the |
|
1864 * partition <a href="#partName">named</a> by this abstract pathname. When |
|
1865 * possible, this method checks for write permissions and other operating |
|
1866 * system restrictions and will therefore usually provide a more accurate |
|
1867 * estimate of how much new data can actually be written than {@link |
|
1868 * #getFreeSpace}. |
|
1869 * |
|
1870 * <p> The returned number of available bytes is a hint, but not a |
|
1871 * guarantee, that it is possible to use most or any of these bytes. The |
|
1872 * number of unallocated bytes is most likely to be accurate immediately |
|
1873 * after this call. It is likely to be made inaccurate by any external |
|
1874 * I/O operations including those made on the system outside of this |
|
1875 * virtual machine. This method makes no guarantee that write operations |
|
1876 * to this file system will succeed. |
|
1877 * |
|
1878 * @return The number of available bytes on the partition or {@code 0L} |
|
1879 * if the abstract pathname does not name a partition. On |
|
1880 * systems where this information is not available, this method |
|
1881 * will be equivalent to a call to {@link #getFreeSpace}. |
|
1882 * |
|
1883 * @throws SecurityException |
|
1884 * If a security manager has been installed and it denies |
|
1885 * {@link RuntimePermission}{@code ("getFileSystemAttributes")} |
|
1886 * or its {@link SecurityManager#checkRead(String)} method denies |
|
1887 * read access to the file named by this abstract pathname |
|
1888 * |
|
1889 * @since 1.6 |
|
1890 */ |
|
1891 public long getUsableSpace() { |
|
1892 SecurityManager sm = System.getSecurityManager(); |
|
1893 if (sm != null) { |
|
1894 sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); |
|
1895 sm.checkRead(path); |
|
1896 } |
|
1897 if (isInvalid()) { |
|
1898 return 0L; |
|
1899 } |
|
1900 return fs.getSpace(this, FileSystem.SPACE_USABLE); |
|
1901 } |
|
1902 |
|
1903 /* -- Temporary files -- */ |
|
1904 |
|
1905 private static class TempDirectory { |
|
1906 private TempDirectory() { } |
|
1907 |
|
1908 // temporary directory location |
|
1909 private static final File tmpdir = new File( |
|
1910 GetPropertyAction.privilegedGetProperty("java.io.tmpdir")); |
|
1911 static File location() { |
|
1912 return tmpdir; |
|
1913 } |
|
1914 |
|
1915 // file name generation |
|
1916 private static final SecureRandom random = new SecureRandom(); |
|
1917 private static int shortenSubName(int subNameLength, int excess, |
|
1918 int nameMin) { |
|
1919 int newLength = Math.max(nameMin, subNameLength - excess); |
|
1920 if (newLength < subNameLength) { |
|
1921 return newLength; |
|
1922 } |
|
1923 return subNameLength; |
|
1924 } |
|
1925 static File generateFile(String prefix, String suffix, File dir) |
|
1926 throws IOException |
|
1927 { |
|
1928 long n = random.nextLong(); |
|
1929 String nus = Long.toUnsignedString(n); |
|
1930 |
|
1931 // Use only the file name from the supplied prefix |
|
1932 prefix = (new File(prefix)).getName(); |
|
1933 |
|
1934 int prefixLength = prefix.length(); |
|
1935 int nusLength = nus.length(); |
|
1936 int suffixLength = suffix.length();; |
|
1937 |
|
1938 String name; |
|
1939 int nameMax = fs.getNameMax(dir.getPath()); |
|
1940 int excess = prefixLength + nusLength + suffixLength - nameMax; |
|
1941 if (excess <= 0) { |
|
1942 name = prefix + nus + suffix; |
|
1943 } else { |
|
1944 // Name exceeds the maximum path component length: shorten it |
|
1945 |
|
1946 // Attempt to shorten the prefix length to no less then 3 |
|
1947 prefixLength = shortenSubName(prefixLength, excess, 3); |
|
1948 excess = prefixLength + nusLength + suffixLength - nameMax; |
|
1949 |
|
1950 if (excess > 0) { |
|
1951 // Attempt to shorten the suffix length to no less than |
|
1952 // 0 or 4 depending on whether it begins with a dot ('.') |
|
1953 suffixLength = shortenSubName(suffixLength, excess, |
|
1954 suffix.indexOf(".") == 0 ? 4 : 0); |
|
1955 suffixLength = shortenSubName(suffixLength, excess, 3); |
|
1956 excess = prefixLength + nusLength + suffixLength - nameMax; |
|
1957 } |
|
1958 |
|
1959 if (excess > 0 && excess <= nusLength - 5) { |
|
1960 // Attempt to shorten the random character string length |
|
1961 // to no less than 5 |
|
1962 nusLength = shortenSubName(nusLength, excess, 5); |
|
1963 } |
|
1964 |
|
1965 StringBuilder sb = |
|
1966 new StringBuilder(prefixLength + nusLength + suffixLength); |
|
1967 sb.append(prefixLength < prefix.length() ? |
|
1968 prefix.substring(0, prefixLength) : prefix); |
|
1969 sb.append(nusLength < nus.length() ? |
|
1970 nus.substring(0, nusLength) : nus); |
|
1971 sb.append(suffixLength < suffix.length() ? |
|
1972 suffix.substring(0, suffixLength) : suffix); |
|
1973 name = sb.toString(); |
|
1974 } |
|
1975 |
|
1976 // Normalize the path component |
|
1977 name = fs.normalize(name); |
|
1978 |
|
1979 File f = new File(dir, name); |
|
1980 if (!name.equals(f.getName()) || f.isInvalid()) { |
|
1981 if (System.getSecurityManager() != null) |
|
1982 throw new IOException("Unable to create temporary file"); |
|
1983 else |
|
1984 throw new IOException("Unable to create temporary file, " |
|
1985 + name); |
|
1986 } |
|
1987 return f; |
|
1988 } |
|
1989 } |
|
1990 |
|
1991 /** |
|
1992 * <p> Creates a new empty file in the specified directory, using the |
|
1993 * given prefix and suffix strings to generate its name. If this method |
|
1994 * returns successfully then it is guaranteed that: |
|
1995 * |
|
1996 * <ol> |
|
1997 * <li> The file denoted by the returned abstract pathname did not exist |
|
1998 * before this method was invoked, and |
|
1999 * <li> Neither this method nor any of its variants will return the same |
|
2000 * abstract pathname again in the current invocation of the virtual |
|
2001 * machine. |
|
2002 * </ol> |
|
2003 * |
|
2004 * This method provides only part of a temporary-file facility. To arrange |
|
2005 * for a file created by this method to be deleted automatically, use the |
|
2006 * {@link #deleteOnExit} method. |
|
2007 * |
|
2008 * <p> The <code>prefix</code> argument must be at least three characters |
|
2009 * long. It is recommended that the prefix be a short, meaningful string |
|
2010 * such as <code>"hjb"</code> or <code>"mail"</code>. The |
|
2011 * <code>suffix</code> argument may be <code>null</code>, in which case the |
|
2012 * suffix <code>".tmp"</code> will be used. |
|
2013 * |
|
2014 * <p> To create the new file, the prefix and the suffix may first be |
|
2015 * adjusted to fit the limitations of the underlying platform. If the |
|
2016 * prefix is too long then it will be truncated, but its first three |
|
2017 * characters will always be preserved. If the suffix is too long then it |
|
2018 * too will be truncated, but if it begins with a period character |
|
2019 * (<code>'.'</code>) then the period and the first three characters |
|
2020 * following it will always be preserved. Once these adjustments have been |
|
2021 * made the name of the new file will be generated by concatenating the |
|
2022 * prefix, five or more internally-generated characters, and the suffix. |
|
2023 * |
|
2024 * <p> If the <code>directory</code> argument is <code>null</code> then the |
|
2025 * system-dependent default temporary-file directory will be used. The |
|
2026 * default temporary-file directory is specified by the system property |
|
2027 * <code>java.io.tmpdir</code>. On UNIX systems the default value of this |
|
2028 * property is typically <code>"/tmp"</code> or <code>"/var/tmp"</code>; on |
|
2029 * Microsoft Windows systems it is typically <code>"C:\\WINNT\\TEMP"</code>. A different |
|
2030 * value may be given to this system property when the Java virtual machine |
|
2031 * is invoked, but programmatic changes to this property are not guaranteed |
|
2032 * to have any effect upon the temporary directory used by this method. |
|
2033 * |
|
2034 * @param prefix The prefix string to be used in generating the file's |
|
2035 * name; must be at least three characters long |
|
2036 * |
|
2037 * @param suffix The suffix string to be used in generating the file's |
|
2038 * name; may be <code>null</code>, in which case the |
|
2039 * suffix <code>".tmp"</code> will be used |
|
2040 * |
|
2041 * @param directory The directory in which the file is to be created, or |
|
2042 * <code>null</code> if the default temporary-file |
|
2043 * directory is to be used |
|
2044 * |
|
2045 * @return An abstract pathname denoting a newly-created empty file |
|
2046 * |
|
2047 * @throws IllegalArgumentException |
|
2048 * If the <code>prefix</code> argument contains fewer than three |
|
2049 * characters |
|
2050 * |
|
2051 * @throws IOException If a file could not be created |
|
2052 * |
|
2053 * @throws SecurityException |
|
2054 * If a security manager exists and its {@link |
|
2055 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
2056 * method does not allow a file to be created |
|
2057 * |
|
2058 * @since 1.2 |
|
2059 */ |
|
2060 public static File createTempFile(String prefix, String suffix, |
|
2061 File directory) |
|
2062 throws IOException |
|
2063 { |
|
2064 if (prefix.length() < 3) { |
|
2065 throw new IllegalArgumentException("Prefix string \"" + prefix + |
|
2066 "\" too short: length must be at least 3"); |
|
2067 } |
|
2068 if (suffix == null) |
|
2069 suffix = ".tmp"; |
|
2070 |
|
2071 File tmpdir = (directory != null) ? directory |
|
2072 : TempDirectory.location(); |
|
2073 SecurityManager sm = System.getSecurityManager(); |
|
2074 File f; |
|
2075 do { |
|
2076 f = TempDirectory.generateFile(prefix, suffix, tmpdir); |
|
2077 |
|
2078 if (sm != null) { |
|
2079 try { |
|
2080 sm.checkWrite(f.getPath()); |
|
2081 } catch (SecurityException se) { |
|
2082 // don't reveal temporary directory location |
|
2083 if (directory == null) |
|
2084 throw new SecurityException("Unable to create temporary file"); |
|
2085 throw se; |
|
2086 } |
|
2087 } |
|
2088 } while ((fs.getBooleanAttributes(f) & FileSystem.BA_EXISTS) != 0); |
|
2089 |
|
2090 if (!fs.createFileExclusively(f.getPath())) |
|
2091 throw new IOException("Unable to create temporary file"); |
|
2092 |
|
2093 return f; |
|
2094 } |
|
2095 |
|
2096 /** |
|
2097 * Creates an empty file in the default temporary-file directory, using |
|
2098 * the given prefix and suffix to generate its name. Invoking this method |
|
2099 * is equivalent to invoking {@link #createTempFile(java.lang.String, |
|
2100 * java.lang.String, java.io.File) |
|
2101 * createTempFile(prefix, suffix, null)}. |
|
2102 * |
|
2103 * <p> The {@link |
|
2104 * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[]) |
|
2105 * Files.createTempFile} method provides an alternative method to create an |
|
2106 * empty file in the temporary-file directory. Files created by that method |
|
2107 * may have more restrictive access permissions to files created by this |
|
2108 * method and so may be more suited to security-sensitive applications. |
|
2109 * |
|
2110 * @param prefix The prefix string to be used in generating the file's |
|
2111 * name; must be at least three characters long |
|
2112 * |
|
2113 * @param suffix The suffix string to be used in generating the file's |
|
2114 * name; may be <code>null</code>, in which case the |
|
2115 * suffix <code>".tmp"</code> will be used |
|
2116 * |
|
2117 * @return An abstract pathname denoting a newly-created empty file |
|
2118 * |
|
2119 * @throws IllegalArgumentException |
|
2120 * If the <code>prefix</code> argument contains fewer than three |
|
2121 * characters |
|
2122 * |
|
2123 * @throws IOException If a file could not be created |
|
2124 * |
|
2125 * @throws SecurityException |
|
2126 * If a security manager exists and its {@link |
|
2127 * java.lang.SecurityManager#checkWrite(java.lang.String)} |
|
2128 * method does not allow a file to be created |
|
2129 * |
|
2130 * @since 1.2 |
|
2131 * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[]) |
|
2132 */ |
|
2133 public static File createTempFile(String prefix, String suffix) |
|
2134 throws IOException |
|
2135 { |
|
2136 return createTempFile(prefix, suffix, null); |
|
2137 } |
|
2138 |
|
2139 /* -- Basic infrastructure -- */ |
|
2140 |
|
2141 /** |
|
2142 * Compares two abstract pathnames lexicographically. The ordering |
|
2143 * defined by this method depends upon the underlying system. On UNIX |
|
2144 * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows |
|
2145 * systems it is not. |
|
2146 * |
|
2147 * @param pathname The abstract pathname to be compared to this abstract |
|
2148 * pathname |
|
2149 * |
|
2150 * @return Zero if the argument is equal to this abstract pathname, a |
|
2151 * value less than zero if this abstract pathname is |
|
2152 * lexicographically less than the argument, or a value greater |
|
2153 * than zero if this abstract pathname is lexicographically |
|
2154 * greater than the argument |
|
2155 * |
|
2156 * @since 1.2 |
|
2157 */ |
|
2158 public int compareTo(File pathname) { |
|
2159 return fs.compare(this, pathname); |
|
2160 } |
|
2161 |
|
2162 /** |
|
2163 * Tests this abstract pathname for equality with the given object. |
|
2164 * Returns <code>true</code> if and only if the argument is not |
|
2165 * <code>null</code> and is an abstract pathname that denotes the same file |
|
2166 * or directory as this abstract pathname. Whether or not two abstract |
|
2167 * pathnames are equal depends upon the underlying system. On UNIX |
|
2168 * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows |
|
2169 * systems it is not. |
|
2170 * |
|
2171 * @param obj The object to be compared with this abstract pathname |
|
2172 * |
|
2173 * @return <code>true</code> if and only if the objects are the same; |
|
2174 * <code>false</code> otherwise |
|
2175 */ |
|
2176 public boolean equals(Object obj) { |
|
2177 if ((obj != null) && (obj instanceof File)) { |
|
2178 return compareTo((File)obj) == 0; |
|
2179 } |
|
2180 return false; |
|
2181 } |
|
2182 |
|
2183 /** |
|
2184 * Computes a hash code for this abstract pathname. Because equality of |
|
2185 * abstract pathnames is inherently system-dependent, so is the computation |
|
2186 * of their hash codes. On UNIX systems, the hash code of an abstract |
|
2187 * pathname is equal to the exclusive <em>or</em> of the hash code |
|
2188 * of its pathname string and the decimal value |
|
2189 * <code>1234321</code>. On Microsoft Windows systems, the hash |
|
2190 * code is equal to the exclusive <em>or</em> of the hash code of |
|
2191 * its pathname string converted to lower case and the decimal |
|
2192 * value <code>1234321</code>. Locale is not taken into account on |
|
2193 * lowercasing the pathname string. |
|
2194 * |
|
2195 * @return A hash code for this abstract pathname |
|
2196 */ |
|
2197 public int hashCode() { |
|
2198 return fs.hashCode(this); |
|
2199 } |
|
2200 |
|
2201 /** |
|
2202 * Returns the pathname string of this abstract pathname. This is just the |
|
2203 * string returned by the {@link #getPath} method. |
|
2204 * |
|
2205 * @return The string form of this abstract pathname |
|
2206 */ |
|
2207 public String toString() { |
|
2208 return getPath(); |
|
2209 } |
|
2210 |
|
2211 /** |
|
2212 * WriteObject is called to save this filename. |
|
2213 * The separator character is saved also so it can be replaced |
|
2214 * in case the path is reconstituted on a different host type. |
|
2215 * |
|
2216 * @serialData Default fields followed by separator character. |
|
2217 */ |
|
2218 private synchronized void writeObject(java.io.ObjectOutputStream s) |
|
2219 throws IOException |
|
2220 { |
|
2221 s.defaultWriteObject(); |
|
2222 s.writeChar(separatorChar); // Add the separator character |
|
2223 } |
|
2224 |
|
2225 /** |
|
2226 * readObject is called to restore this filename. |
|
2227 * The original separator character is read. If it is different |
|
2228 * than the separator character on this system, then the old separator |
|
2229 * is replaced by the local separator. |
|
2230 */ |
|
2231 private synchronized void readObject(java.io.ObjectInputStream s) |
|
2232 throws IOException, ClassNotFoundException |
|
2233 { |
|
2234 ObjectInputStream.GetField fields = s.readFields(); |
|
2235 String pathField = (String)fields.get("path", null); |
|
2236 char sep = s.readChar(); // read the previous separator char |
|
2237 if (sep != separatorChar) |
|
2238 pathField = pathField.replace(sep, separatorChar); |
|
2239 String path = fs.normalize(pathField); |
|
2240 UNSAFE.putObject(this, PATH_OFFSET, path); |
|
2241 UNSAFE.putIntVolatile(this, PREFIX_LENGTH_OFFSET, fs.prefixLength(path)); |
|
2242 } |
|
2243 |
|
2244 private static final jdk.internal.misc.Unsafe UNSAFE |
|
2245 = jdk.internal.misc.Unsafe.getUnsafe(); |
|
2246 private static final long PATH_OFFSET |
|
2247 = UNSAFE.objectFieldOffset(File.class, "path"); |
|
2248 private static final long PREFIX_LENGTH_OFFSET |
|
2249 = UNSAFE.objectFieldOffset(File.class, "prefixLength"); |
|
2250 |
|
2251 /** use serialVersionUID from JDK 1.0.2 for interoperability */ |
|
2252 private static final long serialVersionUID = 301077366599181567L; |
|
2253 |
|
2254 // -- Integration with java.nio.file -- |
|
2255 |
|
2256 private transient volatile Path filePath; |
|
2257 |
|
2258 /** |
|
2259 * Returns a {@link Path java.nio.file.Path} object constructed from the |
|
2260 * this abstract path. The resulting {@code Path} is associated with the |
|
2261 * {@link java.nio.file.FileSystems#getDefault default-filesystem}. |
|
2262 * |
|
2263 * <p> The first invocation of this method works as if invoking it were |
|
2264 * equivalent to evaluating the expression: |
|
2265 * <blockquote><pre> |
|
2266 * {@link java.nio.file.FileSystems#getDefault FileSystems.getDefault}().{@link |
|
2267 * java.nio.file.FileSystem#getPath getPath}(this.{@link #getPath getPath}()); |
|
2268 * </pre></blockquote> |
|
2269 * Subsequent invocations of this method return the same {@code Path}. |
|
2270 * |
|
2271 * <p> If this abstract pathname is the empty abstract pathname then this |
|
2272 * method returns a {@code Path} that may be used to access the current |
|
2273 * user directory. |
|
2274 * |
|
2275 * @return a {@code Path} constructed from this abstract path |
|
2276 * |
|
2277 * @throws java.nio.file.InvalidPathException |
|
2278 * if a {@code Path} object cannot be constructed from the abstract |
|
2279 * path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath}) |
|
2280 * |
|
2281 * @since 1.7 |
|
2282 * @see Path#toFile |
|
2283 */ |
|
2284 public Path toPath() { |
|
2285 Path result = filePath; |
|
2286 if (result == null) { |
|
2287 synchronized (this) { |
|
2288 result = filePath; |
|
2289 if (result == null) { |
|
2290 result = FileSystems.getDefault().getPath(path); |
|
2291 filePath = result; |
|
2292 } |
|
2293 } |
|
2294 } |
|
2295 return result; |
|
2296 } |
|
2297 } |