KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > io > File


1 /*
2  * @(#)File.java 1.122 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.io;
9
10 import java.net.URI JavaDoc;
11 import java.net.URL JavaDoc;
12 import java.net.MalformedURLException JavaDoc;
13 import java.net.URISyntaxException JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Map JavaDoc;
16 import java.util.Hashtable JavaDoc;
17 import java.util.Random JavaDoc;
18 import java.security.AccessController JavaDoc;
19 import java.security.AccessControlException JavaDoc;
20 import sun.security.action.GetPropertyAction;
21
22
23 /**
24  * An abstract representation of file and directory pathnames.
25  *
26  * <p> User interfaces and operating systems use system-dependent <em>pathname
27  * strings</em> to name files and directories. This class presents an
28  * abstract, system-independent view of hierarchical pathnames. An
29  * <em>abstract pathname</em> has two components:
30  *
31  * <ol>
32  * <li> An optional system-dependent <em>prefix</em> string,
33  * such as a disk-drive specifier, <code>"/"</code>&nbsp;for the UNIX root
34  * directory, or <code>"\\\\"</code>&nbsp;for a Microsoft Windows UNC pathname, and
35  * <li> A sequence of zero or more string <em>names</em>.
36  * </ol>
37  *
38  * Each name in an abstract pathname except for the last denotes a directory;
39  * the last name may denote either a directory or a file. The <em>empty</em>
40  * abstract pathname has no prefix and an empty name sequence.
41  *
42  * <p> The conversion of a pathname string to or from an abstract pathname is
43  * inherently system-dependent. When an abstract pathname is converted into a
44  * pathname string, each name is separated from the next by a single copy of
45  * the default <em>separator character</em>. The default name-separator
46  * character is defined by the system property <code>file.separator</code>, and
47  * is made available in the public static fields <code>{@link
48  * #separator}</code> and <code>{@link #separatorChar}</code> of this class.
49  * When a pathname string is converted into an abstract pathname, the names
50  * within it may be separated by the default name-separator character or by any
51  * other name-separator character that is supported by the underlying system.
52  *
53  * <p> A pathname, whether abstract or in string form, may be either
54  * <em>absolute</em> or <em>relative</em>. An absolute pathname is complete in
55  * that no other information is required in order to locate the file that it
56  * denotes. A relative pathname, in contrast, must be interpreted in terms of
57  * information taken from some other pathname. By default the classes in the
58  * <code>java.io</code> package always resolve relative pathnames against the
59  * current user directory. This directory is named by the system property
60  * <code>user.dir</code>, and is typically the directory in which the Java
61  * virtual machine was invoked.
62  *
63  * <p> The prefix concept is used to handle root directories on UNIX platforms,
64  * and drive specifiers, root directories and UNC pathnames on Microsoft Windows platforms,
65  * as follows:
66  *
67  * <ul>
68  *
69  * <li> For UNIX platforms, the prefix of an absolute pathname is always
70  * <code>"/"</code>. Relative pathnames have no prefix. The abstract pathname
71  * denoting the root directory has the prefix <code>"/"</code> and an empty
72  * name sequence.
73  *
74  * <li> For Microsoft Windows platforms, the prefix of a pathname that contains a drive
75  * specifier consists of the drive letter followed by <code>":"</code> and
76  * possibly followed by <code>"\\"</code> if the pathname is absolute. The
77  * prefix of a UNC pathname is <code>"\\\\"</code>; the hostname and the share
78  * name are the first two names in the name sequence. A relative pathname that
79  * does not specify a drive has no prefix.
80  *
81  * </ul>
82  *
83  * <p> Instances of the <code>File</code> class are immutable; that is, once
84  * created, the abstract pathname represented by a <code>File</code> object
85  * will never change.
86  *
87  * @version 1.122, 05/05/04
88  * @author unascribed
89  * @since JDK1.0
90  */

91
92 public class File
93     implements Serializable JavaDoc, Comparable JavaDoc<File JavaDoc>
94 {
95
96     /**
97      * The FileSystem object representing the platform's local file system.
98      */

99     static private FileSystem JavaDoc fs = FileSystem.getFileSystem();
100
101     /**
102      * This abstract pathname's normalized pathname string. A normalized
103      * pathname string uses the default name-separator character and does not
104      * contain any duplicate or redundant separators.
105      *
106      * @serial
107      */

108     private String JavaDoc path;
109
110     /**
111      * The length of this abstract pathname's prefix, or zero if it has no
112      * prefix.
113      */

114     private transient int prefixLength;
115
116     /**
117      * Returns the length of this abstract pathname's prefix.
118      * For use by FileSystem classes.
119      */

120     int getPrefixLength() {
121     return prefixLength;
122     }
123
124     /**
125      * The system-dependent default name-separator character. This field is
126      * initialized to contain the first character of the value of the system
127      * property <code>file.separator</code>. On UNIX systems the value of this
128      * field is <code>'/'</code>; on Microsoft Windows systems it is <code>'\\'</code>.
129      *
130      * @see java.lang.System#getProperty(java.lang.String)
131      */

132     public static final char separatorChar = fs.getSeparator();
133
134     /**
135      * The system-dependent default name-separator character, represented as a
136      * string for convenience. This string contains a single character, namely
137      * <code>{@link #separatorChar}</code>.
138      */

139     public static final String JavaDoc separator = "" + separatorChar;
140
141     /**
142      * The system-dependent path-separator character. This field is
143      * initialized to contain the first character of the value of the system
144      * property <code>path.separator</code>. This character is used to
145      * separate filenames in a sequence of files given as a <em>path list</em>.
146      * On UNIX systems, this character is <code>':'</code>; on Microsoft Windows systems it
147      * is <code>';'</code>.
148      *
149      * @see java.lang.System#getProperty(java.lang.String)
150      */

151     public static final char pathSeparatorChar = fs.getPathSeparator();
152
153     /**
154      * The system-dependent path-separator character, represented as a string
155      * for convenience. This string contains a single character, namely
156      * <code>{@link #pathSeparatorChar}</code>.
157      */

158     public static final String JavaDoc pathSeparator = "" + pathSeparatorChar;
159
160
161     /* -- Constructors -- */
162
163     /**
164      * Internal constructor for already-normalized pathname strings.
165      */

166     private File(String JavaDoc pathname, int prefixLength) {
167     this.path = pathname;
168     this.prefixLength = prefixLength;
169     }
170
171     /**
172      * Internal constructor for already-normalized pathname strings.
173      * The parameter order is used to disambiguate this method from the
174      * public(File, String) constructor.
175      */

176     private File(String JavaDoc child, File JavaDoc parent) {
177         assert parent.path != null;
178         assert (!parent.path.equals(""));
179         this.path = fs.resolve(parent.path, child);
180     this.prefixLength = parent.prefixLength;
181     }
182
183     /**
184      * Creates a new <code>File</code> instance by converting the given
185      * pathname string into an abstract pathname. If the given string is
186      * the empty string, then the result is the empty abstract pathname.
187      *
188      * @param pathname A pathname string
189      * @throws NullPointerException
190      * If the <code>pathname</code> argument is <code>null</code>
191      */

192     public File(String JavaDoc pathname) {
193     if (pathname == null) {
194         throw new NullPointerException JavaDoc();
195     }
196     this.path = fs.normalize(pathname);
197     this.prefixLength = fs.prefixLength(this.path);
198     }
199
200     /* Note: The two-argument File constructors do not interpret an empty
201        parent abstract pathname as the current user directory. An empty parent
202        instead causes the child to be resolved against the system-dependent
203        directory defined by the FileSystem.getDefaultParent method. On Unix
204        this default is "/", while on Microsoft Windows it is "\\". This is required for
205        compatibility with the original behavior of this class. */

206
207     /**
208      * Creates a new <code>File</code> instance from a parent pathname string
209      * and a child pathname string.
210      *
211      * <p> If <code>parent</code> is <code>null</code> then the new
212      * <code>File</code> instance is created as if by invoking the
213      * single-argument <code>File</code> constructor on the given
214      * <code>child</code> pathname string.
215      *
216      * <p> Otherwise the <code>parent</code> pathname string is taken to denote
217      * a directory, and the <code>child</code> pathname string is taken to
218      * denote either a directory or a file. If the <code>child</code> pathname
219      * string is absolute then it is converted into a relative pathname in a
220      * system-dependent way. If <code>parent</code> is the empty string then
221      * the new <code>File</code> instance is created by converting
222      * <code>child</code> into an abstract pathname and resolving the result
223      * against a system-dependent default directory. Otherwise each pathname
224      * string is converted into an abstract pathname and the child abstract
225      * pathname is resolved against the parent.
226      *
227      * @param parent The parent pathname string
228      * @param child The child pathname string
229      * @throws NullPointerException
230      * If <code>child</code> is <code>null</code>
231      */

232     public File(String JavaDoc parent, String JavaDoc child) {
233     if (child == null) {
234         throw new NullPointerException JavaDoc();
235     }
236     if (parent != null) {
237         if (parent.equals("")) {
238         this.path = fs.resolve(fs.getDefaultParent(),
239                        fs.normalize(child));
240         } else {
241         this.path = fs.resolve(fs.normalize(parent),
242                        fs.normalize(child));
243         }
244     } else {
245         this.path = fs.normalize(child);
246     }
247     this.prefixLength = fs.prefixLength(this.path);
248     }
249
250     /**
251      * Creates a new <code>File</code> instance from a parent abstract
252      * pathname and a child pathname string.
253      *
254      * <p> If <code>parent</code> is <code>null</code> then the new
255      * <code>File</code> instance is created as if by invoking the
256      * single-argument <code>File</code> constructor on the given
257      * <code>child</code> pathname string.
258      *
259      * <p> Otherwise the <code>parent</code> abstract pathname is taken to
260      * denote a directory, and the <code>child</code> pathname string is taken
261      * to denote either a directory or a file. If the <code>child</code>
262      * pathname string is absolute then it is converted into a relative
263      * pathname in a system-dependent way. If <code>parent</code> is the empty
264      * abstract pathname then the new <code>File</code> instance is created by
265      * converting <code>child</code> into an abstract pathname and resolving
266      * the result against a system-dependent default directory. Otherwise each
267      * pathname string is converted into an abstract pathname and the child
268      * abstract pathname is resolved against the parent.
269      *
270      * @param parent The parent abstract pathname
271      * @param child The child pathname string
272      * @throws NullPointerException
273      * If <code>child</code> is <code>null</code>
274      */

275     public File(File JavaDoc parent, String JavaDoc child) {
276     if (child == null) {
277         throw new NullPointerException JavaDoc();
278     }
279     if (parent != null) {
280         if (parent.path.equals("")) {
281         this.path = fs.resolve(fs.getDefaultParent(),
282                        fs.normalize(child));
283         } else {
284         this.path = fs.resolve(parent.path,
285                        fs.normalize(child));
286         }
287     } else {
288         this.path = fs.normalize(child);
289     }
290     this.prefixLength = fs.prefixLength(this.path);
291     }
292
293     /**
294      * Creates a new <tt>File</tt> instance by converting the given
295      * <tt>file:</tt> URI into an abstract pathname.
296      *
297      * <p> The exact form of a <tt>file:</tt> URI is system-dependent, hence
298      * the transformation performed by this constructor is also
299      * system-dependent.
300      *
301      * <p> For a given abstract pathname <i>f</i> it is guaranteed that
302      *
303      * <blockquote><tt>
304      * new File(</tt><i>&nbsp;f</i><tt>.{@link #toURI() toURI}()).equals(</tt><i>&nbsp;f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
305      * </tt></blockquote>
306      *
307      * so long as the original abstract pathname, the URI, and the new abstract
308      * pathname are all created in (possibly different invocations of) the same
309      * Java virtual machine. This relationship typically does not hold,
310      * however, when a <tt>file:</tt> URI that is created in a virtual machine
311      * on one operating system is converted into an abstract pathname in a
312      * virtual machine on a different operating system.
313      *
314      * @param uri
315      * An absolute, hierarchical URI with a scheme equal to
316      * <tt>"file"</tt>, a non-empty path component, and undefined
317      * authority, query, and fragment components
318      *
319      * @throws NullPointerException
320      * If <tt>uri</tt> is <tt>null</tt>
321      *
322      * @throws IllegalArgumentException
323      * If the preconditions on the parameter do not hold
324      *
325      * @see #toURI()
326      * @see java.net.URI
327      * @since 1.4
328      */

329     public File(URI JavaDoc uri) {
330
331     // Check our many preconditions
332
if (!uri.isAbsolute())
333         throw new IllegalArgumentException JavaDoc("URI is not absolute");
334     if (uri.isOpaque())
335         throw new IllegalArgumentException JavaDoc("URI is not hierarchical");
336     String JavaDoc scheme = uri.getScheme();
337     if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
338         throw new IllegalArgumentException JavaDoc("URI scheme is not \"file\"");
339     if (uri.getAuthority() != null)
340         throw new IllegalArgumentException JavaDoc("URI has an authority component");
341     if (uri.getFragment() != null)
342         throw new IllegalArgumentException JavaDoc("URI has a fragment component");
343     if (uri.getQuery() != null)
344         throw new IllegalArgumentException JavaDoc("URI has a query component");
345     String JavaDoc p = uri.getPath();
346     if (p.equals(""))
347         throw new IllegalArgumentException JavaDoc("URI path component is empty");
348
349     // Okay, now initialize
350
p = fs.fromURIPath(p);
351     if (File.separatorChar != '/')
352         p = p.replace('/', File.separatorChar);
353     this.path = fs.normalize(p);
354     this.prefixLength = fs.prefixLength(this.path);
355     }
356
357
358     /* -- Path-component accessors -- */
359
360     /**
361      * Returns the name of the file or directory denoted by this abstract
362      * pathname. This is just the last name in the pathname's name
363      * sequence. If the pathname's name sequence is empty, then the empty
364      * string is returned.
365      *
366      * @return The name of the file or directory denoted by this abstract
367      * pathname, or the empty string if this pathname's name sequence
368      * is empty
369      */

370     public String JavaDoc getName() {
371     int index = path.lastIndexOf(separatorChar);
372     if (index < prefixLength) return path.substring(prefixLength);
373     return path.substring(index + 1);
374     }
375
376     /**
377      * Returns the pathname string of this abstract pathname's parent, or
378      * <code>null</code> if this pathname does not name a parent directory.
379      *
380      * <p> The <em>parent</em> of an abstract pathname consists of the
381      * pathname's prefix, if any, and each name in the pathname's name
382      * sequence except for the last. If the name sequence is empty then
383      * the pathname does not name a parent directory.
384      *
385      * @return The pathname string of the parent directory named by this
386      * abstract pathname, or <code>null</code> if this pathname
387      * does not name a parent
388      */

389     public String JavaDoc getParent() {
390     int index = path.lastIndexOf(separatorChar);
391     if (index < prefixLength) {
392         if ((prefixLength > 0) && (path.length() > prefixLength))
393         return path.substring(0, prefixLength);
394         return null;
395     }
396     return path.substring(0, index);
397     }
398
399     /**
400      * Returns the abstract pathname of this abstract pathname's parent,
401      * or <code>null</code> if this pathname does not name a parent
402      * directory.
403      *
404      * <p> The <em>parent</em> of an abstract pathname consists of the
405      * pathname's prefix, if any, and each name in the pathname's name
406      * sequence except for the last. If the name sequence is empty then
407      * the pathname does not name a parent directory.
408      *
409      * @return The abstract pathname of the parent directory named by this
410      * abstract pathname, or <code>null</code> if this pathname
411      * does not name a parent
412      *
413      * @since 1.2
414      */

415     public File JavaDoc getParentFile() {
416     String JavaDoc p = this.getParent();
417     if (p == null) return null;
418     return new File JavaDoc(p, this.prefixLength);
419     }
420
421     /**
422      * Converts this abstract pathname into a pathname string. The resulting
423      * string uses the {@link #separator default name-separator character} to
424      * separate the names in the name sequence.
425      *
426      * @return The string form of this abstract pathname
427      */

428     public String JavaDoc getPath() {
429     return path;
430     }
431
432
433     /* -- Path operations -- */
434
435     /**
436      * Tests whether this abstract pathname is absolute. The definition of
437      * absolute pathname is system dependent. On UNIX systems, a pathname is
438      * absolute if its prefix is <code>"/"</code>. On Microsoft Windows systems, a
439      * pathname is absolute if its prefix is a drive specifier followed by
440      * <code>"\\"</code>, or if its prefix is <code>"\\\\"</code>.
441      *
442      * @return <code>true</code> if this abstract pathname is absolute,
443      * <code>false</code> otherwise
444      */

445     public boolean isAbsolute() {
446     return fs.isAbsolute(this);
447     }
448
449     /**
450      * Returns the absolute pathname string of this abstract pathname.
451      *
452      * <p> If this abstract pathname is already absolute, then the pathname
453      * string is simply returned as if by the <code>{@link #getPath}</code>
454      * method. If this abstract pathname is the empty abstract pathname then
455      * the pathname string of the current user directory, which is named by the
456      * system property <code>user.dir</code>, is returned. Otherwise this
457      * pathname is resolved in a system-dependent way. On UNIX systems, a
458      * relative pathname is made absolute by resolving it against the current
459      * user directory. On Microsoft Windows systems, a relative pathname is made absolute
460      * by resolving it against the current directory of the drive named by the
461      * pathname, if any; if not, it is resolved against the current user
462      * directory.
463      *
464      * @return The absolute pathname string denoting the same file or
465      * directory as this abstract pathname
466      *
467      * @throws SecurityException
468      * If a required system property value cannot be accessed.
469      *
470      * @see java.io.File#isAbsolute()
471      */

472     public String JavaDoc getAbsolutePath() {
473     return fs.resolve(this);
474     }
475
476     /**
477      * Returns the absolute form of this abstract pathname. Equivalent to
478      * <code>new&nbsp;File(this.{@link #getAbsolutePath}())</code>.
479      *
480      * @return The absolute abstract pathname denoting the same file or
481      * directory as this abstract pathname
482      *
483      * @throws SecurityException
484      * If a required system property value cannot be accessed.
485      *
486      * @since 1.2
487      */

488     public File JavaDoc getAbsoluteFile() {
489         String JavaDoc absPath = getAbsolutePath();
490     return new File JavaDoc(absPath, fs.prefixLength(absPath));
491     }
492
493     /**
494      * Returns the canonical pathname string of this abstract pathname.
495      *
496      * <p> A canonical pathname is both absolute and unique. The precise
497      * definition of canonical form is system-dependent. This method first
498      * converts this pathname to absolute form if necessary, as if by invoking the
499      * {@link #getAbsolutePath} method, and then maps it to its unique form in a
500      * system-dependent way. This typically involves removing redundant names
501      * such as <tt>"."</tt> and <tt>".."</tt> from the pathname, resolving
502      * symbolic links (on UNIX platforms), and converting drive letters to a
503      * standard case (on Microsoft Windows platforms).
504      *
505      * <p> Every pathname that denotes an existing file or directory has a
506      * unique canonical form. Every pathname that denotes a nonexistent file
507      * or directory also has a unique canonical form. The canonical form of
508      * the pathname of a nonexistent file or directory may be different from
509      * the canonical form of the same pathname after the file or directory is
510      * created. Similarly, the canonical form of the pathname of an existing
511      * file or directory may be different from the canonical form of the same
512      * pathname after the file or directory is deleted.
513      *
514      * @return The canonical pathname string denoting the same file or
515      * directory as this abstract pathname
516      *
517      * @throws IOException
518      * If an I/O error occurs, which is possible because the
519      * construction of the canonical pathname may require
520      * filesystem queries
521      *
522      * @throws SecurityException
523      * If a required system property value cannot be accessed, or
524      * if a security manager exists and its <code>{@link
525      * java.lang.SecurityManager#checkRead}</code> method denies
526      * read access to the file
527      *
528      * @since JDK1.1
529      */

530     public String JavaDoc getCanonicalPath() throws IOException JavaDoc {
531     return fs.canonicalize(fs.resolve(this));
532     }
533
534     /**
535      * Returns the canonical form of this abstract pathname. Equivalent to
536      * <code>new&nbsp;File(this.{@link #getCanonicalPath}())</code>.
537      *
538      * @return The canonical pathname string denoting the same file or
539      * directory as this abstract pathname
540      *
541      * @throws IOException
542      * If an I/O error occurs, which is possible because the
543      * construction of the canonical pathname may require
544      * filesystem queries
545      *
546      * @throws SecurityException
547      * If a required system property value cannot be accessed, or
548      * if a security manager exists and its <code>{@link
549      * java.lang.SecurityManager#checkRead}</code> method denies
550      * read access to the file
551      *
552      * @since 1.2
553      */

554     public File JavaDoc getCanonicalFile() throws IOException JavaDoc {
555         String JavaDoc canonPath = getCanonicalPath();
556     return new File JavaDoc(canonPath, fs.prefixLength(canonPath));
557     }
558
559     private static String JavaDoc slashify(String JavaDoc path, boolean isDirectory) {
560     String JavaDoc p = path;
561     if (File.separatorChar != '/')
562         p = p.replace(File.separatorChar, '/');
563     if (!p.startsWith("/"))
564         p = "/" + p;
565     if (!p.endsWith("/") && isDirectory)
566         p = p + "/";
567     return p;
568     }
569
570     /**
571      * Converts this abstract pathname into a <code>file:</code> URL. The
572      * exact form of the URL is system-dependent. If it can be determined that
573      * the file denoted by this abstract pathname is a directory, then the
574      * resulting URL will end with a slash.
575      *
576      * <p> <b>Usage note:</b> This method does not automatically escape
577      * characters that are illegal in URLs. It is recommended that new code
578      * convert an abstract pathname into a URL by first converting it into a
579      * URI, via the {@link #toURI() toURI} method, and then converting the URI
580      * into a URL via the {@link java.net.URI#toURL() URI.toURL} method.
581      *
582      * @return A URL object representing the equivalent file URL
583      *
584      * @throws MalformedURLException
585      * If the path cannot be parsed as a URL
586      *
587      * @see #toURI()
588      * @see java.net.URI
589      * @see java.net.URI#toURL()
590      * @see java.net.URL
591      * @since 1.2
592      */

593     public URL JavaDoc toURL() throws MalformedURLException JavaDoc {
594     return new URL JavaDoc("file", "", slashify(getAbsolutePath(), isDirectory()));
595     }
596
597     /**
598      * Constructs a <tt>file:</tt> URI that represents this abstract pathname.
599      *
600      * <p> The exact form of the URI is system-dependent. If it can be
601      * determined that the file denoted by this abstract pathname is a
602      * directory, then the resulting URI will end with a slash.
603      *
604      * <p> For a given abstract pathname <i>f</i>, it is guaranteed that
605      *
606      * <blockquote><tt>
607      * new {@link #File(java.net.URI) File}(</tt><i>&nbsp;f</i><tt>.toURI()).equals(</tt><i>&nbsp;f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
608      * </tt></blockquote>
609      *
610      * so long as the original abstract pathname, the URI, and the new abstract
611      * pathname are all created in (possibly different invocations of) the same
612      * Java virtual machine. Due to the system-dependent nature of abstract
613      * pathnames, however, this relationship typically does not hold when a
614      * <tt>file:</tt> URI that is created in a virtual machine on one operating
615      * system is converted into an abstract pathname in a virtual machine on a
616      * different operating system.
617      *
618      * @return An absolute, hierarchical URI with a scheme equal to
619      * <tt>"file"</tt>, a path representing this abstract pathname,
620      * and undefined authority, query, and fragment components
621      *
622      * @see #File(java.net.URI)
623      * @see java.net.URI
624      * @see java.net.URI#toURL()
625      * @since 1.4
626      */

627     public URI JavaDoc toURI() {
628     try {
629         File JavaDoc f = getAbsoluteFile();
630         String JavaDoc sp = slashify(f.getPath(), f.isDirectory());
631         if (sp.startsWith("//"))
632         sp = "//" + sp;
633         return new URI JavaDoc("file", null, sp, null);
634     } catch (URISyntaxException JavaDoc x) {
635         throw new Error JavaDoc(x); // Can't happen
636
}
637     }
638
639
640     /* -- Attribute accessors -- */
641
642     /**
643      * Tests whether the application can read the file denoted by this
644      * abstract pathname.
645      *
646      * @return <code>true</code> if and only if the file specified by this
647      * abstract pathname exists <em>and</em> can be read by the
648      * application; <code>false</code> otherwise
649      *
650      * @throws SecurityException
651      * If a security manager exists and its <code>{@link
652      * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
653      * method denies read access to the file
654      */

655     public boolean canRead() {
656     SecurityManager JavaDoc security = System.getSecurityManager();
657     if (security != null) {
658         security.checkRead(path);
659     }
660     return fs.checkAccess(this, false);
661     }
662
663     /**
664      * Tests whether the application can modify the file denoted by this
665      * abstract pathname.
666      *
667      * @return <code>true</code> if and only if the file system actually
668      * contains a file denoted by this abstract pathname <em>and</em>
669      * the application is allowed to write to the file;
670      * <code>false</code> otherwise.
671      *
672      * @throws SecurityException
673      * If a security manager exists and its <code>{@link
674      * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
675      * method denies write access to the file
676      */

677     public boolean canWrite() {
678     SecurityManager JavaDoc security = System.getSecurityManager();
679     if (security != null) {
680         security.checkWrite(path);
681     }
682     return fs.checkAccess(this, true);
683     }
684
685     /**
686      * Tests whether the file or directory denoted by this abstract pathname
687      * exists.
688      *
689      * @return <code>true</code> if and only if the file or directory denoted
690      * by this abstract pathname exists; <code>false</code> otherwise
691      *
692      * @throws SecurityException
693      * If a security manager exists and its <code>{@link
694      * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
695      * method denies read access to the file or directory
696      */

697     public boolean exists() {
698     SecurityManager JavaDoc security = System.getSecurityManager();
699     if (security != null) {
700         security.checkRead(path);
701     }
702     return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
703     }
704
705     /**
706      * Tests whether the file denoted by this abstract pathname is a
707      * directory.
708      *
709      * @return <code>true</code> if and only if the file denoted by this
710      * abstract pathname exists <em>and</em> is a directory;
711      * <code>false</code> otherwise
712      *
713      * @throws SecurityException
714      * If a security manager exists and its <code>{@link
715      * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
716      * method denies read access to the file
717      */

718     public boolean isDirectory() {
719     SecurityManager JavaDoc security = System.getSecurityManager();
720     if (security != null) {
721         security.checkRead(path);
722     }
723     return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
724         != 0);
725     }
726
727     /**
728      * Tests whether the file denoted by this abstract pathname is a normal
729      * file. A file is <em>normal</em> if it is not a directory and, in
730      * addition, satisfies other system-dependent criteria. Any non-directory
731      * file created by a Java application is guaranteed to be a normal file.
732      *
733      * @return <code>true</code> if and only if the file denoted by this
734      * abstract pathname exists <em>and</em> is a normal file;
735      * <code>false</code> otherwise
736      *
737      * @throws SecurityException
738      * If a security manager exists and its <code>{@link
739      * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
740      * method denies read access to the file
741      */

742     public boolean isFile() {
743     SecurityManager JavaDoc security = System.getSecurityManager();
744     if (security != null) {
745         security.checkRead(path);
746     }
747     return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
748     }
749
750     /**
751      * Tests whether the file named by this abstract pathname is a hidden
752      * file. The exact definition of <em>hidden</em> is system-dependent. On
753      * UNIX systems, a file is considered to be hidden if its name begins with
754      * a period character (<code>'.'</code>). On Microsoft Windows systems, a file is
755      * considered to be hidden if it has been marked as such in the filesystem.
756      *
757      * @return <code>true</code> if and only if the file denoted by this
758      * abstract pathname is hidden according to the conventions of the
759      * underlying platform
760      *
761      * @throws SecurityException
762      * If a security manager exists and its <code>{@link
763      * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
764      * method denies read access to the file
765      *
766      * @since 1.2
767      */

768     public boolean isHidden() {
769     SecurityManager JavaDoc security = System.getSecurityManager();
770     if (security != null) {
771         security.checkRead(path);
772     }
773     return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
774     }
775
776     /**
777      * Returns the time that the file denoted by this abstract pathname was
778      * last modified.
779      *
780      * @return A <code>long</code> value representing the time the file was
781      * last modified, measured in milliseconds since the epoch
782      * (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
783      * file does not exist or if an I/O error occurs
784      *
785      * @throws SecurityException
786      * If a security manager exists and its <code>{@link
787      * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
788      * method denies read access to the file
789      */

790     public long lastModified() {
791     SecurityManager JavaDoc security = System.getSecurityManager();
792     if (security != null) {
793         security.checkRead(path);
794     }
795     return fs.getLastModifiedTime(this);
796     }
797
798     /**
799      * Returns the length of the file denoted by this abstract pathname.
800      * The return value is unspecified if this pathname denotes a directory.
801      *
802      * @return The length, in bytes, of the file denoted by this abstract
803      * pathname, or <code>0L</code> if the file does not exist
804      *
805      * @throws SecurityException
806      * If a security manager exists and its <code>{@link
807      * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
808      * method denies read access to the file
809      */

810     public long length() {
811     SecurityManager JavaDoc security = System.getSecurityManager();
812     if (security != null) {
813         security.checkRead(path);
814     }
815     return fs.getLength(this);
816     }
817
818
819     /* -- File operations -- */
820
821     /**
822      * Atomically creates a new, empty file named by this abstract pathname if
823      * and only if a file with this name does not yet exist. The check for the
824      * existence of the file and the creation of the file if it does not exist
825      * are a single operation that is atomic with respect to all other
826      * filesystem activities that might affect the file.
827      * <P>
828      * Note: this method should <i>not</i> be used for file-locking, as
829      * the resulting protocol cannot be made to work reliably. The
830      * {@link java.nio.channels.FileLock FileLock}
831      * facility should be used instead.
832      *
833      * @return <code>true</code> if the named file does not exist and was
834      * successfully created; <code>false</code> if the named file
835      * already exists
836      *
837      * @throws IOException
838      * If an I/O error occurred
839      *
840      * @throws SecurityException
841      * If a security manager exists and its <code>{@link
842      * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
843      * method denies write access to the file
844      *
845      * @since 1.2
846      */

847     public boolean createNewFile() throws IOException JavaDoc {
848     SecurityManager JavaDoc security = System.getSecurityManager();
849     if (security != null) security.checkWrite(path);
850     return fs.createFileExclusively(path);
851     }
852
853     /**
854      * Deletes the file or directory denoted by this abstract pathname. If
855      * this pathname denotes a directory, then the directory must be empty in
856      * order to be deleted.
857      *
858      * @return <code>true</code> if and only if the file or directory is
859      * successfully deleted; <code>false</code> otherwise
860      *
861      * @throws SecurityException
862      * If a security manager exists and its <code>{@link
863      * java.lang.SecurityManager#checkDelete}</code> method denies
864      * delete access to the file
865      */

866     public boolean delete() {
867     SecurityManager JavaDoc security = System.getSecurityManager();
868     if (security != null) {
869         security.checkDelete(path);
870     }
871     return fs.delete(this);
872     }
873
874     /**
875      * Requests that the file or directory denoted by this abstract
876      * pathname be deleted when the virtual machine terminates.
877      * Deletion will be attempted only for normal termination of the
878      * virtual machine, as defined by the Java Language Specification.
879      *
880      * <p> Once deletion has been requested, it is not possible to cancel the
881      * request. This method should therefore be used with care.
882      *
883      * <P>
884      * Note: this method should <i>not</i> be used for file-locking, as
885      * the resulting protocol cannot be made to work reliably. The
886      * {@link java.nio.channels.FileLock FileLock}
887      * facility should be used instead.
888      *
889      * @throws SecurityException
890      * If a security manager exists and its <code>{@link
891      * java.lang.SecurityManager#checkDelete}</code> method denies
892      * delete access to the file
893      *
894      * @see #delete
895      *
896      * @since 1.2
897      */

898     public void deleteOnExit() {
899     SecurityManager JavaDoc security = System.getSecurityManager();
900     if (security != null) {
901         security.checkDelete(path);
902     }
903     fs.deleteOnExit(this);
904     }
905
906     /**
907      * Returns an array of strings naming the files and directories in the
908      * directory denoted by this abstract pathname.
909      *
910      * <p> If this abstract pathname does not denote a directory, then this
911      * method returns <code>null</code>. Otherwise an array of strings is
912      * returned, one for each file or directory in the directory. Names
913      * denoting the directory itself and the directory's parent directory are
914      * not included in the result. Each string is a file name rather than a
915      * complete path.
916      *
917      * <p> There is no guarantee that the name strings in the resulting array
918      * will appear in any specific order; they are not, in particular,
919      * guaranteed to appear in alphabetical order.
920      *
921      * @return An array of strings naming the files and directories in the
922      * directory denoted by this abstract pathname. The array will be
923      * empty if the directory is empty. Returns <code>null</code> if
924      * this abstract pathname does not denote a directory, or if an
925      * I/O error occurs.
926      *
927      * @throws SecurityException
928      * If a security manager exists and its <code>{@link
929      * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
930      * method denies read access to the directory
931      */

932     public String JavaDoc[] list() {
933     SecurityManager JavaDoc security = System.getSecurityManager();
934     if (security != null) {
935         security.checkRead(path);
936     }
937     return fs.list(this);
938     }
939
940     /**
941      * Returns an array of strings naming the files and directories in the
942      * directory denoted by this abstract pathname that satisfy the specified
943      * filter. The behavior of this method is the same as that of the
944      * <code>{@link #list()}</code> method, except that the strings in the
945      * returned array must satisfy the filter. If the given
946      * <code>filter</code> is <code>null</code> then all names are accepted.
947      * Otherwise, a name satisfies the filter if and only if the value
948      * <code>true</code> results when the <code>{@link
949      * FilenameFilter#accept}</code> method of the filter is invoked on this
950      * abstract pathname and the name of a file or directory in the directory
951      * that it denotes.
952      *
953      * @param filter A filename filter
954      *
955      * @return An array of strings naming the files and directories in the
956      * directory denoted by this abstract pathname that were accepted
957      * by the given <code>filter</code>. The array will be empty if
958      * the directory is empty or if no names were accepted by the
959      * filter. Returns <code>null</code> if this abstract pathname
960      * does not denote a directory, or if an I/O error occurs.
961      *
962      * @throws SecurityException
963      * If a security manager exists and its <code>{@link
964      * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
965      * method denies read access to the directory
966      */

967     public String