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 JavaDoc[] list(FilenameFilter JavaDoc filter) {
968     String JavaDoc names[] = list();
969     if ((names == null) || (filter == null)) {
970         return names;
971     }
972     ArrayList JavaDoc v = new ArrayList JavaDoc();
973     for (int i = 0 ; i < names.length ; i++) {
974         if (filter.accept(this, names[i])) {
975         v.add(names[i]);
976         }
977     }
978     return (String JavaDoc[])(v.toArray(new String JavaDoc[0]));
979     }
980
981     /**
982      * Returns an array of abstract pathnames denoting the files in the
983      * directory denoted by this abstract pathname.
984      *
985      * <p> If this abstract pathname does not denote a directory, then this
986      * method returns <code>null</code>. Otherwise an array of
987      * <code>File</code> objects is returned, one for each file or directory in
988      * the directory. Pathnames denoting the directory itself and the
989      * directory's parent directory are not included in the result. Each
990      * resulting abstract pathname is constructed from this abstract pathname
991      * using the <code>{@link #File(java.io.File, java.lang.String)
992      * File(File,&nbsp;String)}</code> constructor. Therefore if this pathname
993      * is absolute then each resulting pathname is absolute; if this pathname
994      * is relative then each resulting pathname will be relative to the same
995      * directory.
996      *
997      * <p> There is no guarantee that the name strings in the resulting array
998      * will appear in any specific order; they are not, in particular,
999      * guaranteed to appear in alphabetical order.
1000     *
1001     * @return An array of abstract pathnames denoting the files and
1002     * directories in the directory denoted by this abstract
1003     * pathname. The array will be empty if the directory is
1004     * empty. Returns <code>null</code> if this abstract pathname
1005     * does not denote a directory, or if an I/O error occurs.
1006     *
1007     * @throws SecurityException
1008     * If a security manager exists and its <code>{@link
1009     * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1010     * method denies read access to the directory
1011     *
1012     * @since 1.2
1013     */

1014    public File JavaDoc[] listFiles() {
1015    String JavaDoc[] ss = list();
1016    if (ss == null) return null;
1017    int n = ss.length;
1018    File JavaDoc[] fs = new File JavaDoc[n];
1019    for (int i = 0; i < n; i++) {
1020        fs[i] = new File JavaDoc(ss[i], this);
1021    }
1022    return fs;
1023    }
1024
1025    /**
1026     * Returns an array of abstract pathnames denoting the files and
1027     * directories in the directory denoted by this abstract pathname that
1028     * satisfy the specified filter. The behavior of this method is the
1029     * same as that of the <code>{@link #listFiles()}</code> method, except
1030     * that the pathnames in the returned array must satisfy the filter.
1031     * If the given <code>filter</code> is <code>null</code> then all
1032     * pathnames are accepted. Otherwise, a pathname satisfies the filter
1033     * if and only if the value <code>true</code> results when the
1034     * <code>{@link FilenameFilter#accept}</code> method of the filter is
1035     * invoked on this abstract pathname and the name of a file or
1036     * directory in the directory that it denotes.
1037     *
1038     * @param filter A filename filter
1039     *
1040     * @return An array of abstract pathnames denoting the files and
1041     * directories in the directory denoted by this abstract
1042     * pathname. The array will be empty if the directory is
1043     * empty. Returns <code>null</code> if this abstract pathname
1044     * does not denote a directory, or if an I/O error occurs.
1045     *
1046     * @throws SecurityException
1047     * If a security manager exists and its <code>{@link
1048     * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1049     * method denies read access to the directory
1050     *
1051     * @since 1.2
1052     */

1053    public File JavaDoc[] listFiles(FilenameFilter JavaDoc filter) {
1054    String JavaDoc ss[] = list();
1055    if (ss == null) return null;
1056    ArrayList JavaDoc v = new ArrayList JavaDoc();
1057    for (int i = 0 ; i < ss.length ; i++) {
1058        if ((filter == null) || filter.accept(this, ss[i])) {
1059        v.add(new File JavaDoc(ss[i], this));
1060        }
1061    }
1062    return (File JavaDoc[])(v.toArray(new File JavaDoc[0]));
1063    }
1064
1065    /**
1066     * Returns an array of abstract pathnames denoting the files and
1067     * directories in the directory denoted by this abstract pathname that
1068     * satisfy the specified filter. The behavior of this method is the
1069     * same as that of the <code>{@link #listFiles()}</code> method, except
1070     * that the pathnames in the returned array must satisfy the filter.
1071     * If the given <code>filter</code> is <code>null</code> then all
1072     * pathnames are accepted. Otherwise, a pathname satisfies the filter
1073     * if and only if the value <code>true</code> results when the
1074     * <code>{@link FileFilter#accept(java.io.File)}</code> method of
1075     * the filter is invoked on the pathname.
1076     *
1077     * @param filter A file filter
1078     *
1079     * @return An array of abstract pathnames denoting the files and
1080     * directories in the directory denoted by this abstract
1081     * pathname. The array will be empty if the directory is
1082     * empty. Returns <code>null</code> if this abstract pathname
1083     * does not denote a directory, or if an I/O error occurs.
1084     *
1085     * @throws SecurityException
1086     * If a security manager exists and its <code>{@link
1087     * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1088     * method denies read access to the directory
1089     *
1090     * @since 1.2
1091     */

1092    public File JavaDoc[] listFiles(FileFilter JavaDoc filter) {
1093    String JavaDoc ss[] = list();
1094    if (ss == null) return null;
1095    ArrayList JavaDoc v = new ArrayList JavaDoc();
1096    for (int i = 0 ; i < ss.length ; i++) {
1097        File JavaDoc f = new File JavaDoc(ss[i], this);
1098        if ((filter == null) || filter.accept(f)) {
1099        v.add(f);
1100        }
1101    }
1102    return (File JavaDoc[])(v.toArray(new File JavaDoc[0]));
1103    }
1104
1105    /**
1106     * Creates the directory named by this abstract pathname.
1107     *
1108     * @return <code>true</code> if and only if the directory was
1109     * created; <code>false</code> otherwise
1110     *
1111     * @throws SecurityException
1112     * If a security manager exists and its <code>{@link
1113     * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1114     * method does not permit the named directory to be created
1115     */

1116    public boolean mkdir() {
1117    SecurityManager JavaDoc security = System.getSecurityManager();
1118    if (security != null) {
1119        security.checkWrite(path);
1120    }
1121    return fs.createDirectory(this);
1122    }
1123
1124    /**
1125     * Creates the directory named by this abstract pathname, including any
1126     * necessary but nonexistent parent directories. Note that if this
1127     * operation fails it may have succeeded in creating some of the necessary
1128     * parent directories.
1129     *
1130     * @return <code>true</code> if and only if the directory was created,
1131     * along with all necessary parent directories; <code>false</code>
1132     * otherwise
1133     *
1134     * @throws SecurityException
1135     * If a security manager exists and its <code>{@link
1136     * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1137     * method does not permit verification of the existence of the
1138     * named directory and all necessary parent directories; or if
1139     * the <code>{@link
1140     * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1141     * method does not permit the named directory and all necessary
1142     * parent directories to be created
1143     */

1144    public boolean mkdirs() {
1145    if (exists()) {
1146        return false;
1147    }
1148    if (mkdir()) {
1149        return true;
1150    }
1151        File JavaDoc canonFile = null;
1152        try {
1153            canonFile = getCanonicalFile();
1154        } catch (IOException JavaDoc e) {
1155            return false;
1156        }
1157    String JavaDoc parent = canonFile.getParent();
1158        return (parent != null) &&
1159               (new File JavaDoc(parent, fs.prefixLength(parent)).mkdirs() &&
1160                                    canonFile.mkdir());
1161    }
1162
1163    /**
1164     * Renames the file denoted by this abstract pathname.
1165     *
1166     * <p> Many aspects of the behavior of this method are inherently
1167     * platform-dependent: The rename operation might not be able to move a
1168     * file from one filesystem to another, it might not be atomic, and it
1169     * might not succeed if a file with the destination abstract pathname
1170     * already exists. The return value should always be checked to make sure
1171     * that the rename operation was successful.
1172     *
1173     * @param dest The new abstract pathname for the named file
1174     *
1175     * @return <code>true</code> if and only if the renaming succeeded;
1176     * <code>false</code> otherwise
1177     *
1178     * @throws SecurityException
1179     * If a security manager exists and its <code>{@link
1180     * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1181     * method denies write access to either the old or new pathnames
1182     *
1183     * @throws NullPointerException
1184     * If parameter <code>dest</code> is <code>null</code>
1185     */

1186    public boolean renameTo(File JavaDoc dest) {
1187    SecurityManager JavaDoc security = System.getSecurityManager();
1188    if (security != null) {
1189        security.checkWrite(path);
1190        security.checkWrite(dest.path);
1191    }
1192    return fs.rename(this, dest);
1193    }
1194
1195    /**
1196     * Sets the last-modified time of the file or directory named by this
1197     * abstract pathname.
1198     *
1199     * <p> All platforms support file-modification times to the nearest second,
1200     * but some provide more precision. The argument will be truncated to fit
1201     * the supported precision. If the operation succeeds and no intervening
1202     * operations on the file take place, then the next invocation of the
1203     * <code>{@link #lastModified}</code> method will return the (possibly
1204     * truncated) <code>time</code> argument that was passed to this method.
1205     *
1206     * @param time The new last-modified time, measured in milliseconds since
1207     * the epoch (00:00:00 GMT, January 1, 1970)
1208     *
1209     * @return <code>true</code> if and only if the operation succeeded;
1210     * <code>false</code> otherwise
1211     *
1212     * @throws IllegalArgumentException If the argument is negative
1213     *
1214     * @throws SecurityException
1215     * If a security manager exists and its <code>{@link
1216     * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1217     * method denies write access to the named file
1218     *
1219     * @since 1.2
1220     */

1221    public boolean setLastModified(long time) {
1222    if (time < 0) throw new IllegalArgumentException JavaDoc("Negative time");
1223    SecurityManager JavaDoc security = System.getSecurityManager();
1224    if (security != null) {
1225        security.checkWrite(path);
1226    }
1227    return fs.setLastModifiedTime(this, time);
1228    }
1229
1230    /**
1231     * Marks the file or directory named by this abstract pathname so that
1232     * only read operations are allowed. After invoking this method the file
1233     * or directory is guaranteed not to change until it is either deleted or
1234     * marked to allow write access. Whether or not a read-only file or
1235     * directory may be deleted depends upon the underlying system.
1236     *
1237     * @return <code>true</code> if and only if the operation succeeded;
1238     * <code>false</code> otherwise
1239     *
1240     * @throws SecurityException
1241     * If a security manager exists and its <code>{@link
1242     * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1243     * method denies write access to the named file
1244     *
1245     * @since 1.2
1246     */

1247    public boolean setReadOnly() {
1248    SecurityManager JavaDoc security = System.getSecurityManager();
1249    if (security != null) {
1250        security.checkWrite(path);
1251    }
1252    return fs.setReadOnly(this);
1253    }
1254
1255
1256    /* -- Filesystem interface -- */
1257
1258    /**
1259     * List the available filesystem roots.
1260     *
1261     * <p> A particular Java platform may support zero or more
1262     * hierarchically-organized file systems. Each file system has a
1263     * <code>root</code> directory from which all other files in that file
1264     * system can be reached. Windows platforms, for example, have a root
1265     * directory for each active drive; UNIX platforms have a single root
1266     * directory, namely <code>"/"</code>. The set of available filesystem
1267     * roots is affected by various system-level operations such as the insertion
1268     * or ejection of removable media and the disconnecting or unmounting of
1269     * physical or virtual disk drives.
1270     *
1271     * <p> This method returns an array of <code>File</code> objects that
1272     * denote the root directories of the available filesystem roots. It is
1273     * guaranteed that the canonical pathname of any file physically present on
1274     * the local machine will begin with one of the roots returned by this
1275     * method.
1276     *
1277     * <p> The canonical pathname of a file that resides on some other machine
1278     * and is accessed via a remote-filesystem protocol such as SMB or NFS may
1279     * or may not begin with one of the roots returned by this method. If the
1280     * pathname of a remote file is syntactically indistinguishable from the
1281     * pathname of a local file then it will begin with one of the roots
1282     * returned by this method. Thus, for example, <code>File</code> objects
1283     * denoting the root directories of the mapped network drives of a Windows
1284     * platform will be returned by this method, while <code>File</code>
1285     * objects containing UNC pathnames will not be returned by this method.
1286     *
1287     * <p> Unlike most methods in this class, this method does not throw
1288     * security exceptions. If a security manager exists and its <code>{@link
1289     * java.lang.SecurityManager#checkRead(java.lang.String)}</code> method
1290     * denies read access to a particular root directory, then that directory
1291     * will not appear in the result.
1292     *
1293     * @return An array of <code>File</code> objects denoting the available
1294     * filesystem roots, or <code>null</code> if the set of roots
1295     * could not be determined. The array will be empty if there are
1296     * no filesystem roots.
1297     *
1298     * @since 1.2
1299     */

1300    public static File JavaDoc[] listRoots() {
1301    return fs.listRoots();
1302    }
1303
1304
1305    /* -- Temporary files -- */
1306
1307    private static final Object JavaDoc tmpFileLock = new Object JavaDoc();
1308
1309    private static int counter = -1; /* Protected by tmpFileLock */
1310
1311    private static File JavaDoc generateFile(String JavaDoc prefix, String JavaDoc suffix, File JavaDoc dir)
1312    throws IOException JavaDoc
1313    {
1314    if (counter == -1) {
1315        counter = new Random JavaDoc().nextInt() & 0xffff;
1316    }
1317    counter++;
1318    return new File JavaDoc(dir, prefix + Integer.toString(counter) + suffix);
1319    }
1320
1321    private static String JavaDoc tmpdir; /* Protected by tmpFileLock */
1322
1323    private static String JavaDoc getTempDir() {
1324    if (tmpdir == null) {
1325        GetPropertyAction a = new GetPropertyAction("java.io.tmpdir");
1326        tmpdir = ((String JavaDoc) AccessController.doPrivileged(a));
1327            tmpdir = fs.normalize(tmpdir);
1328    }
1329    return tmpdir;
1330    }
1331
1332    private static boolean checkAndCreate(String JavaDoc filename, SecurityManager JavaDoc sm)
1333    throws IOException JavaDoc
1334    {
1335    if (sm != null) {
1336        try {
1337        sm.checkWrite(filename);
1338        } catch (AccessControlException JavaDoc x) {
1339        /* Throwing the original AccessControlException could disclose
1340           the location of the default temporary directory, so we
1341           re-throw a more innocuous SecurityException */

1342        throw new SecurityException JavaDoc("Unable to create temporary file");
1343        }
1344    }
1345    return fs.createFileExclusively(filename);
1346    }
1347
1348    /**
1349     * <p> Creates a new empty file in the specified directory, using the
1350     * given prefix and suffix strings to generate its name. If this method
1351     * returns successfully then it is guaranteed that:
1352     *
1353     * <ol>
1354     * <li> The file denoted by the returned abstract pathname did not exist
1355     * before this method was invoked, and
1356     * <li> Neither this method nor any of its variants will return the same
1357     * abstract pathname again in the current invocation of the virtual
1358     * machine.
1359     * </ol>
1360     *
1361     * This method provides only part of a temporary-file facility. To arrange
1362     * for a file created by this method to be deleted automatically, use the
1363     * <code>{@link #deleteOnExit}</code> method.
1364     *
1365     * <p> The <code>prefix</code> argument must be at least three characters
1366     * long. It is recommended that the prefix be a short, meaningful string
1367     * such as <code>"hjb"</code> or <code>"mail"</code>. The
1368     * <code>suffix</code> argument may be <code>null</code>, in which case the
1369     * suffix <code>".tmp"</code> will be used.
1370     *
1371     * <p> To create the new file, the prefix and the suffix may first be
1372     * adjusted to fit the limitations of the underlying platform. If the
1373     * prefix is too long then it will be truncated, but its first three
1374     * characters will always be preserved. If the suffix is too long then it
1375     * too will be truncated, but if it begins with a period character
1376     * (<code>'.'</code>) then the period and the first three characters
1377     * following it will always be preserved. Once these adjustments have been
1378     * made the name of the new file will be generated by concatenating the
1379     * prefix, five or more internally-generated characters, and the suffix.
1380     *
1381     * <p> If the <code>directory</code> argument is <code>null</code> then the
1382     * system-dependent default temporary-file directory will be used. The
1383     * default temporary-file directory is specified by the system property
1384     * <code>java.io.tmpdir</code>. On UNIX systems the default value of this
1385     * property is typically <code>"/tmp"</code> or <code>"/var/tmp"</code>; on
1386     * Microsoft Windows systems it is typically <code>"C:\\WINNT\\TEMP"</code>. A different
1387     * value may be given to this system property when the Java virtual machine
1388     * is invoked, but programmatic changes to this property are not guaranteed
1389     * to have any effect upon the temporary directory used by this method.
1390     *
1391     * @param prefix The prefix string to be used in generating the file's
1392     * name; must be at least three characters long
1393     *
1394     * @param suffix The suffix string to be used in generating the file's
1395     * name; may be <code>null</code>, in which case the
1396     * suffix <code>".tmp"</code> will be used
1397     *
1398     * @param directory The directory in which the file is to be created, or
1399     * <code>null</code> if the default temporary-file
1400     * directory is to be used
1401     *
1402     * @return An abstract pathname denoting a newly-created empty file
1403     *
1404     * @throws IllegalArgumentException
1405     * If the <code>prefix</code> argument contains fewer than three
1406     * characters
1407     *
1408     * @throws IOException If a file could not be created
1409     *
1410     * @throws SecurityException
1411     * If a security manager exists and its <code>{@link
1412     * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1413     * method does not allow a file to be created
1414     *
1415     * @since 1.2
1416     */

1417    public static File JavaDoc createTempFile(String JavaDoc prefix, String JavaDoc suffix,
1418                      File JavaDoc directory)
1419        throws IOException JavaDoc
1420    {
1421    if (prefix == null) throw new NullPointerException JavaDoc();
1422    if (prefix.length() < 3)
1423        throw new IllegalArgumentException JavaDoc("Prefix string too short");
1424    String JavaDoc s = (suffix == null) ? ".tmp" : suffix;
1425    synchronized (tmpFileLock) {
1426        if (directory == null) {
1427                String JavaDoc tmpDir = getTempDir();
1428        directory = new File JavaDoc(tmpDir, fs.prefixLength(tmpDir));
1429        }
1430        SecurityManager JavaDoc sm = System.getSecurityManager();
1431        File JavaDoc f;
1432        do {
1433        f = generateFile(prefix, s, directory);
1434        } while (!checkAndCreate(f.getPath(), sm));
1435        return f;
1436    }
1437    }
1438
1439    /**
1440     * Creates an empty file in the default temporary-file directory, using
1441     * the given prefix and suffix to generate its name. Invoking this method
1442     * is equivalent to invoking <code>{@link #createTempFile(java.lang.String,
1443     * java.lang.String, java.io.File)
1444     * createTempFile(prefix,&nbsp;suffix,&nbsp;null)}</code>.
1445     *
1446     * @param prefix The prefix string to be used in generating the file's
1447     * name; must be at least three characters long
1448     *
1449     * @param suffix The suffix string to be used in generating the file's
1450     * name; may be <code>null</code>, in which case the
1451     * suffix <code>".tmp"</code> will be used
1452     *
1453     * @return An abstract pathname denoting a newly-created empty file
1454     *
1455     * @throws IllegalArgumentException
1456     * If the <code>prefix</code> argument contains fewer than three
1457     * characters
1458     *
1459     * @throws IOException If a file could not be created
1460     *
1461     * @throws SecurityException
1462     * If a security manager exists and its <code>{@link
1463     * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1464     * method does not allow a file to be created
1465     *
1466     * @since 1.2
1467     */

1468    public static File JavaDoc createTempFile(String JavaDoc prefix, String JavaDoc suffix)
1469    throws IOException JavaDoc
1470    {
1471    return createTempFile(prefix, suffix, null);
1472    }
1473
1474
1475    /* -- Basic infrastructure -- */
1476
1477    /**
1478     * Compares two abstract pathnames lexicographically. The ordering
1479     * defined by this method depends upon the underlying system. On UNIX
1480     * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
1481     * systems it is not.
1482     *
1483     * @param pathname The abstract pathname to be compared to this abstract
1484     * pathname
1485     *
1486     * @return Zero if the argument is equal to this abstract pathname, a
1487     * value less than zero if this abstract pathname is
1488     * lexicographically less than the argument, or a value greater
1489     * than zero if this abstract pathname is lexicographically
1490     * greater than the argument
1491     *
1492     * @since 1.2
1493     */

1494    public int compareTo(File JavaDoc pathname) {
1495    return fs.compare(this, pathname);
1496    }
1497
1498    /**
1499     * Tests this abstract pathname for equality with the given object.
1500     * Returns <code>true</code> if and only if the argument is not
1501     * <code>null</code> and is an abstract pathname that denotes the same file
1502     * or directory as this abstract pathname. Whether or not two abstract
1503     * pathnames are equal depends upon the underlying system. On UNIX
1504     * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
1505     * systems it is not.
1506     *
1507     * @param obj The object to be compared with this abstract pathname
1508     *
1509     * @return <code>true</code> if and only if the objects are the same;
1510     * <code>false</code> otherwise
1511     */

1512    public boolean equals(Object JavaDoc obj) {
1513    if ((obj != null) && (obj instanceof File JavaDoc)) {
1514        return compareTo((File JavaDoc)obj) == 0;
1515    }
1516    return false;
1517    }
1518
1519    /**
1520     * Computes a hash code for this abstract pathname. Because equality of
1521     * abstract pathnames is inherently system-dependent, so is the computation
1522     * of their hash codes. On UNIX systems, the hash code of an abstract
1523     * pathname is equal to the exclusive <em>or</em> of the hash code
1524     * of its pathname string and the decimal value
1525     * <code>1234321</code>. On Microsoft Windows systems, the hash
1526     * code is equal to the exclusive <em>or</em> of the hash code of
1527     * its pathname string converted to lower case and the decimal
1528     * value <code>1234321</code>.
1529     *
1530     * @return A hash code for this abstract pathname
1531     */

1532    public int hashCode() {
1533    return fs.hashCode(this);
1534    }
1535
1536    /**
1537     * Returns the pathname string of this abstract pathname. This is just the
1538     * string returned by the <code>{@link #getPath}</code> method.
1539     *
1540     * @return The string form of this abstract pathname
1541     */

1542    public String JavaDoc toString() {
1543    return getPath();
1544    }
1545
1546    /**
1547     * WriteObject is called to save this filename.
1548     * The separator character is saved also so it can be replaced
1549     * in case the path is reconstituted on a different host type.
1550     */

1551    private synchronized void writeObject(java.io.ObjectOutputStream JavaDoc s)
1552        throws IOException JavaDoc
1553    {
1554    s.defaultWriteObject();
1555    s.writeChar(this.separatorChar); // Add the separator character
1556
}
1557
1558    /**
1559     * readObject is called to restore this filename.
1560     * The original separator character is read. If it is different
1561     * than the separator character on this system, then the old separator
1562     * is replaced by the local separator.
1563     */

1564    private synchronized void readObject(java.io.ObjectInputStream JavaDoc s)
1565         throws IOException JavaDoc, ClassNotFoundException JavaDoc
1566    {
1567    s.defaultReadObject();
1568    char sep = s.readChar(); // read the previous separator char
1569
if (sep != separatorChar)
1570        this.path = this.path.replace(sep, separatorChar);
1571    this.path = fs.normalize(this.path);
1572    this.prefixLength = fs.prefixLength(this.path);
1573    }
1574
1575    /** use serialVersionUID from JDK 1.0.2 for interoperability */
1576    private static final long serialVersionUID = 301077366599181567L;
1577
1578}
1579
Popular Tags