0001 /*
0002 * Copyright 1994-2007 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package java.io;
0027
0028 import java.net.URI;
0029 import java.net.URL;
0030 import java.net.MalformedURLException;
0031 import java.net.URISyntaxException;
0032 import java.util.ArrayList;
0033 import java.util.Map;
0034 import java.util.Hashtable;
0035 import java.util.Random;
0036 import java.security.AccessController;
0037 import java.security.AccessControlException;
0038 import sun.security.action.GetPropertyAction;
0039
0040 /**
0041 * An abstract representation of file and directory pathnames.
0042 *
0043 * <p> User interfaces and operating systems use system-dependent <em>pathname
0044 * strings</em> to name files and directories. This class presents an
0045 * abstract, system-independent view of hierarchical pathnames. An
0046 * <em>abstract pathname</em> has two components:
0047 *
0048 * <ol>
0049 * <li> An optional system-dependent <em>prefix</em> string,
0050 * such as a disk-drive specifier, <code>"/"</code> for the UNIX root
0051 * directory, or <code>"\\\\"</code> for a Microsoft Windows UNC pathname, and
0052 * <li> A sequence of zero or more string <em>names</em>.
0053 * </ol>
0054 *
0055 * The first name in an abstract pathname may be a directory name or, in the
0056 * case of Microsoft Windows UNC pathnames, a hostname. Each subsequent name
0057 * in an abstract pathname denotes a directory; the last name may denote
0058 * either a directory or a file. The <em>empty</em> abstract pathname has no
0059 * prefix and an empty name sequence.
0060 *
0061 * <p> The conversion of a pathname string to or from an abstract pathname is
0062 * inherently system-dependent. When an abstract pathname is converted into a
0063 * pathname string, each name is separated from the next by a single copy of
0064 * the default <em>separator character</em>. The default name-separator
0065 * character is defined by the system property <code>file.separator</code>, and
0066 * is made available in the public static fields <code>{@link
0067 * #separator}</code> and <code>{@link #separatorChar}</code> of this class.
0068 * When a pathname string is converted into an abstract pathname, the names
0069 * within it may be separated by the default name-separator character or by any
0070 * other name-separator character that is supported by the underlying system.
0071 *
0072 * <p> A pathname, whether abstract or in string form, may be either
0073 * <em>absolute</em> or <em>relative</em>. An absolute pathname is complete in
0074 * that no other information is required in order to locate the file that it
0075 * denotes. A relative pathname, in contrast, must be interpreted in terms of
0076 * information taken from some other pathname. By default the classes in the
0077 * <code>java.io</code> package always resolve relative pathnames against the
0078 * current user directory. This directory is named by the system property
0079 * <code>user.dir</code>, and is typically the directory in which the Java
0080 * virtual machine was invoked.
0081 *
0082 * <p> The <em>parent</em> of an abstract pathname may be obtained by invoking
0083 * the {@link #getParent} method of this class and consists of the pathname's
0084 * prefix and each name in the pathname's name sequence except for the last.
0085 * Each directory's absolute pathname is an ancestor of any <tt>File</tt>
0086 * object with an absolute abstract pathname which begins with the directory's
0087 * absolute pathname. For example, the directory denoted by the abstract
0088 * pathname <tt>"/usr"</tt> is an ancestor of the directory denoted by the
0089 * pathname <tt>"/usr/local/bin"</tt>.
0090 *
0091 * <p> The prefix concept is used to handle root directories on UNIX platforms,
0092 * and drive specifiers, root directories and UNC pathnames on Microsoft Windows platforms,
0093 * as follows:
0094 *
0095 * <ul>
0096 *
0097 * <li> For UNIX platforms, the prefix of an absolute pathname is always
0098 * <code>"/"</code>. Relative pathnames have no prefix. The abstract pathname
0099 * denoting the root directory has the prefix <code>"/"</code> and an empty
0100 * name sequence.
0101 *
0102 * <li> For Microsoft Windows platforms, the prefix of a pathname that contains a drive
0103 * specifier consists of the drive letter followed by <code>":"</code> and
0104 * possibly followed by <code>"\\"</code> if the pathname is absolute. The
0105 * prefix of a UNC pathname is <code>"\\\\"</code>; the hostname and the share
0106 * name are the first two names in the name sequence. A relative pathname that
0107 * does not specify a drive has no prefix.
0108 *
0109 * </ul>
0110 *
0111 * <p> Instances of this class may or may not denote an actual file-system
0112 * object such as a file or a directory. If it does denote such an object
0113 * then that object resides in a <i>partition</i>. A partition is an
0114 * operating system-specific portion of storage for a file system. A single
0115 * storage device (e.g. a physical disk-drive, flash memory, CD-ROM) may
0116 * contain multiple partitions. The object, if any, will reside on the
0117 * partition <a name="partName">named</a> by some ancestor of the absolute
0118 * form of this pathname.
0119 *
0120 * <p> A file system may implement restrictions to certain operations on the
0121 * actual file-system object, such as reading, writing, and executing. These
0122 * restrictions are collectively known as <i>access permissions</i>. The file
0123 * system may have multiple sets of access permissions on a single object.
0124 * For example, one set may apply to the object's <i>owner</i>, and another
0125 * may apply to all other users. The access permissions on an object may
0126 * cause some methods in this class to fail.
0127 *
0128 * <p> Instances of the <code>File</code> class are immutable; that is, once
0129 * created, the abstract pathname represented by a <code>File</code> object
0130 * will never change.
0131 *
0132 * @version 1.147, 05/05/07
0133 * @author unascribed
0134 * @since JDK1.0
0135 */
0136
0137 public class File implements Serializable, Comparable<File> {
0138
0139 /**
0140 * The FileSystem object representing the platform's local file system.
0141 */
0142 static private FileSystem fs = FileSystem.getFileSystem();
0143
0144 /**
0145 * This abstract pathname's normalized pathname string. A normalized
0146 * pathname string uses the default name-separator character and does not
0147 * contain any duplicate or redundant separators.
0148 *
0149 * @serial
0150 */
0151 private String path;
0152
0153 /**
0154 * The length of this abstract pathname's prefix, or zero if it has no
0155 * prefix.
0156 */
0157 private transient int prefixLength;
0158
0159 /**
0160 * Returns the length of this abstract pathname's prefix.
0161 * For use by FileSystem classes.
0162 */
0163 int getPrefixLength() {
0164 return prefixLength;
0165 }
0166
0167 /**
0168 * The system-dependent default name-separator character. This field is
0169 * initialized to contain the first character of the value of the system
0170 * property <code>file.separator</code>. On UNIX systems the value of this
0171 * field is <code>'/'</code>; on Microsoft Windows systems it is <code>'\\'</code>.
0172 *
0173 * @see java.lang.System#getProperty(java.lang.String)
0174 */
0175 public static final char separatorChar = fs.getSeparator();
0176
0177 /**
0178 * The system-dependent default name-separator character, represented as a
0179 * string for convenience. This string contains a single character, namely
0180 * <code>{@link #separatorChar}</code>.
0181 */
0182 public static final String separator = "" + separatorChar;
0183
0184 /**
0185 * The system-dependent path-separator character. This field is
0186 * initialized to contain the first character of the value of the system
0187 * property <code>path.separator</code>. This character is used to
0188 * separate filenames in a sequence of files given as a <em>path list</em>.
0189 * On UNIX systems, this character is <code>':'</code>; on Microsoft Windows systems it
0190 * is <code>';'</code>.
0191 *
0192 * @see java.lang.System#getProperty(java.lang.String)
0193 */
0194 public static final char pathSeparatorChar = fs.getPathSeparator();
0195
0196 /**
0197 * The system-dependent path-separator character, represented as a string
0198 * for convenience. This string contains a single character, namely
0199 * <code>{@link #pathSeparatorChar}</code>.
0200 */
0201 public static final String pathSeparator = "" + pathSeparatorChar;
0202
0203 /* -- Constructors -- */
0204
0205 /**
0206 * Internal constructor for already-normalized pathname strings.
0207 */
0208 private File(String pathname, int prefixLength) {
0209 this .path = pathname;
0210 this .prefixLength = prefixLength;
0211 }
0212
0213 /**
0214 * Internal constructor for already-normalized pathname strings.
0215 * The parameter order is used to disambiguate this method from the
0216 * public(File, String) constructor.
0217 */
0218 private File(String child, File parent) {
0219 assert parent.path != null;
0220 assert (!parent.path.equals(""));
0221 this .path = fs.resolve(parent.path, child);
0222 this .prefixLength = parent.prefixLength;
0223 }
0224
0225 /**
0226 * Creates a new <code>File</code> instance by converting the given
0227 * pathname string into an abstract pathname. If the given string is
0228 * the empty string, then the result is the empty abstract pathname.
0229 *
0230 * @param pathname A pathname string
0231 * @throws NullPointerException
0232 * If the <code>pathname</code> argument is <code>null</code>
0233 */
0234 public File(String pathname) {
0235 if (pathname == null) {
0236 throw new NullPointerException();
0237 }
0238 this .path = fs.normalize(pathname);
0239 this .prefixLength = fs.prefixLength(this .path);
0240 }
0241
0242 /* Note: The two-argument File constructors do not interpret an empty
0243 parent abstract pathname as the current user directory. An empty parent
0244 instead causes the child to be resolved against the system-dependent
0245 directory defined by the FileSystem.getDefaultParent method. On Unix
0246 this default is "/", while on Microsoft Windows it is "\\". This is required for
0247 compatibility with the original behavior of this class. */
0248
0249 /**
0250 * Creates a new <code>File</code> instance from a parent pathname string
0251 * and a child pathname string.
0252 *
0253 * <p> If <code>parent</code> is <code>null</code> then the new
0254 * <code>File</code> instance is created as if by invoking the
0255 * single-argument <code>File</code> constructor on the given
0256 * <code>child</code> pathname string.
0257 *
0258 * <p> Otherwise the <code>parent</code> pathname string is taken to denote
0259 * a directory, and the <code>child</code> pathname string is taken to
0260 * denote either a directory or a file. If the <code>child</code> pathname
0261 * string is absolute then it is converted into a relative pathname in a
0262 * system-dependent way. If <code>parent</code> is the empty string then
0263 * the new <code>File</code> instance is created by converting
0264 * <code>child</code> into an abstract pathname and resolving the result
0265 * against a system-dependent default directory. Otherwise each pathname
0266 * string is converted into an abstract pathname and the child abstract
0267 * pathname is resolved against the parent.
0268 *
0269 * @param parent The parent pathname string
0270 * @param child The child pathname string
0271 * @throws NullPointerException
0272 * If <code>child</code> is <code>null</code>
0273 */
0274 public File(String parent, String child) {
0275 if (child == null) {
0276 throw new NullPointerException();
0277 }
0278 if (parent != null) {
0279 if (parent.equals("")) {
0280 this .path = fs.resolve(fs.getDefaultParent(), fs
0281 .normalize(child));
0282 } else {
0283 this .path = fs.resolve(fs.normalize(parent), fs
0284 .normalize(child));
0285 }
0286 } else {
0287 this .path = fs.normalize(child);
0288 }
0289 this .prefixLength = fs.prefixLength(this .path);
0290 }
0291
0292 /**
0293 * Creates a new <code>File</code> instance from a parent abstract
0294 * pathname and a child pathname string.
0295 *
0296 * <p> If <code>parent</code> is <code>null</code> then the new
0297 * <code>File</code> instance is created as if by invoking the
0298 * single-argument <code>File</code> constructor on the given
0299 * <code>child</code> pathname string.
0300 *
0301 * <p> Otherwise the <code>parent</code> abstract pathname is taken to
0302 * denote a directory, and the <code>child</code> pathname string is taken
0303 * to denote either a directory or a file. If the <code>child</code>
0304 * pathname string is absolute then it is converted into a relative
0305 * pathname in a system-dependent way. If <code>parent</code> is the empty
0306 * abstract pathname then the new <code>File</code> instance is created by
0307 * converting <code>child</code> into an abstract pathname and resolving
0308 * the result against a system-dependent default directory. Otherwise each
0309 * pathname string is converted into an abstract pathname and the child
0310 * abstract pathname is resolved against the parent.
0311 *
0312 * @param parent The parent abstract pathname
0313 * @param child The child pathname string
0314 * @throws NullPointerException
0315 * If <code>child</code> is <code>null</code>
0316 */
0317 public File(File parent, String child) {
0318 if (child == null) {
0319 throw new NullPointerException();
0320 }
0321 if (parent != null) {
0322 if (parent.path.equals("")) {
0323 this .path = fs.resolve(fs.getDefaultParent(), fs
0324 .normalize(child));
0325 } else {
0326 this .path = fs
0327 .resolve(parent.path, fs.normalize(child));
0328 }
0329 } else {
0330 this .path = fs.normalize(child);
0331 }
0332 this .prefixLength = fs.prefixLength(this .path);
0333 }
0334
0335 /**
0336 * Creates a new <tt>File</tt> instance by converting the given
0337 * <tt>file:</tt> URI into an abstract pathname.
0338 *
0339 * <p> The exact form of a <tt>file:</tt> URI is system-dependent, hence
0340 * the transformation performed by this constructor is also
0341 * system-dependent.
0342 *
0343 * <p> For a given abstract pathname <i>f</i> it is guaranteed that
0344 *
0345 * <blockquote><tt>
0346 * new File(</tt><i> f</i><tt>.{@link #toURI() toURI}()).equals(</tt><i> f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
0347 * </tt></blockquote>
0348 *
0349 * so long as the original abstract pathname, the URI, and the new abstract
0350 * pathname are all created in (possibly different invocations of) the same
0351 * Java virtual machine. This relationship typically does not hold,
0352 * however, when a <tt>file:</tt> URI that is created in a virtual machine
0353 * on one operating system is converted into an abstract pathname in a
0354 * virtual machine on a different operating system.
0355 *
0356 * @param uri
0357 * An absolute, hierarchical URI with a scheme equal to
0358 * <tt>"file"</tt>, a non-empty path component, and undefined
0359 * authority, query, and fragment components
0360 *
0361 * @throws NullPointerException
0362 * If <tt>uri</tt> is <tt>null</tt>
0363 *
0364 * @throws IllegalArgumentException
0365 * If the preconditions on the parameter do not hold
0366 *
0367 * @see #toURI()
0368 * @see java.net.URI
0369 * @since 1.4
0370 */
0371 public File(URI uri) {
0372
0373 // Check our many preconditions
0374 if (!uri.isAbsolute())
0375 throw new IllegalArgumentException("URI is not absolute");
0376 if (uri.isOpaque())
0377 throw new IllegalArgumentException(
0378 "URI is not hierarchical");
0379 String scheme = uri.getScheme();
0380 if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
0381 throw new IllegalArgumentException(
0382 "URI scheme is not \"file\"");
0383 if (uri.getAuthority() != null)
0384 throw new IllegalArgumentException(
0385 "URI has an authority component");
0386 if (uri.getFragment() != null)
0387 throw new IllegalArgumentException(
0388 "URI has a fragment component");
0389 if (uri.getQuery() != null)
0390 throw new IllegalArgumentException(
0391 "URI has a query component");
0392 String p = uri.getPath();
0393 if (p.equals(""))
0394 throw new IllegalArgumentException(
0395 "URI path component is empty");
0396
0397 // Okay, now initialize
0398 p = fs.fromURIPath(p);
0399 if (File.separatorChar != '/')
0400 p = p.replace('/', File.separatorChar);
0401 this .path = fs.normalize(p);
0402 this .prefixLength = fs.prefixLength(this .path);
0403 }
0404
0405 /* -- Path-component accessors -- */
0406
0407 /**
0408 * Returns the name of the file or directory denoted by this abstract
0409 * pathname. This is just the last name in the pathname's name
0410 * sequence. If the pathname's name sequence is empty, then the empty
0411 * string is returned.
0412 *
0413 * @return The name of the file or directory denoted by this abstract
0414 * pathname, or the empty string if this pathname's name sequence
0415 * is empty
0416 */
0417 public String getName() {
0418 int index = path.lastIndexOf(separatorChar);
0419 if (index < prefixLength)
0420 return path.substring(prefixLength);
0421 return path.substring(index + 1);
0422 }
0423
0424 /**
0425 * Returns the pathname string of this abstract pathname's parent, or
0426 * <code>null</code> if this pathname does not name a parent directory.
0427 *
0428 * <p> The <em>parent</em> of an abstract pathname consists of the
0429 * pathname's prefix, if any, and each name in the pathname's name
0430 * sequence except for the last. If the name sequence is empty then
0431 * the pathname does not name a parent directory.
0432 *
0433 * @return The pathname string of the parent directory named by this
0434 * abstract pathname, or <code>null</code> if this pathname
0435 * does not name a parent
0436 */
0437 public String getParent() {
0438 int index = path.lastIndexOf(separatorChar);
0439 if (index < prefixLength) {
0440 if ((prefixLength > 0) && (path.length() > prefixLength))
0441 return path.substring(0, prefixLength);
0442 return null;
0443 }
0444 return path.substring(0, index);
0445 }
0446
0447 /**
0448 * Returns the abstract pathname of this abstract pathname's parent,
0449 * or <code>null</code> if this pathname does not name a parent
0450 * directory.
0451 *
0452 * <p> The <em>parent</em> of an abstract pathname consists of the
0453 * pathname's prefix, if any, and each name in the pathname's name
0454 * sequence except for the last. If the name sequence is empty then
0455 * the pathname does not name a parent directory.
0456 *
0457 * @return The abstract pathname of the parent directory named by this
0458 * abstract pathname, or <code>null</code> if this pathname
0459 * does not name a parent
0460 *
0461 * @since 1.2
0462 */
0463 public File getParentFile() {
0464 String p = this .getParent();
0465 if (p == null)
0466 return null;
0467 return new File(p, this .prefixLength);
0468 }
0469
0470 /**
0471 * Converts this abstract pathname into a pathname string. The resulting
0472 * string uses the {@link #separator default name-separator character} to
0473 * separate the names in the name sequence.
0474 *
0475 * @return The string form of this abstract pathname
0476 */
0477 public String getPath() {
0478 return path;
0479 }
0480
0481 /* -- Path operations -- */
0482
0483 /**
0484 * Tests whether this abstract pathname is absolute. The definition of
0485 * absolute pathname is system dependent. On UNIX systems, a pathname is
0486 * absolute if its prefix is <code>"/"</code>. On Microsoft Windows systems, a
0487 * pathname is absolute if its prefix is a drive specifier followed by
0488 * <code>"\\"</code>, or if its prefix is <code>"\\\\"</code>.
0489 *
0490 * @return <code>true</code> if this abstract pathname is absolute,
0491 * <code>false</code> otherwise
0492 */
0493 public boolean isAbsolute() {
0494 return fs.isAbsolute(this );
0495 }
0496
0497 /**
0498 * Returns the absolute pathname string of this abstract pathname.
0499 *
0500 * <p> If this abstract pathname is already absolute, then the pathname
0501 * string is simply returned as if by the <code>{@link #getPath}</code>
0502 * method. If this abstract pathname is the empty abstract pathname then
0503 * the pathname string of the current user directory, which is named by the
0504 * system property <code>user.dir</code>, is returned. Otherwise this
0505 * pathname is resolved in a system-dependent way. On UNIX systems, a
0506 * relative pathname is made absolute by resolving it against the current
0507 * user directory. On Microsoft Windows systems, a relative pathname is made absolute
0508 * by resolving it against the current directory of the drive named by the
0509 * pathname, if any; if not, it is resolved against the current user
0510 * directory.
0511 *
0512 * @return The absolute pathname string denoting the same file or
0513 * directory as this abstract pathname
0514 *
0515 * @throws SecurityException
0516 * If a required system property value cannot be accessed.
0517 *
0518 * @see java.io.File#isAbsolute()
0519 */
0520 public String getAbsolutePath() {
0521 return fs.resolve(this );
0522 }
0523
0524 /**
0525 * Returns the absolute form of this abstract pathname. Equivalent to
0526 * <code>new File(this.{@link #getAbsolutePath})</code>.
0527 *
0528 * @return The absolute abstract pathname denoting the same file or
0529 * directory as this abstract pathname
0530 *
0531 * @throws SecurityException
0532 * If a required system property value cannot be accessed.
0533 *
0534 * @since 1.2
0535 */
0536 public File getAbsoluteFile() {
0537 String absPath = getAbsolutePath();
0538 return new File(absPath, fs.prefixLength(absPath));
0539 }
0540
0541 /**
0542 * Returns the canonical pathname string of this abstract pathname.
0543 *
0544 * <p> A canonical pathname is both absolute and unique. The precise
0545 * definition of canonical form is system-dependent. This method first
0546 * converts this pathname to absolute form if necessary, as if by invoking the
0547 * {@link #getAbsolutePath} method, and then maps it to its unique form in a
0548 * system-dependent way. This typically involves removing redundant names
0549 * such as <tt>"."</tt> and <tt>".."</tt> from the pathname, resolving
0550 * symbolic links (on UNIX platforms), and converting drive letters to a
0551 * standard case (on Microsoft Windows platforms).
0552 *
0553 * <p> Every pathname that denotes an existing file or directory has a
0554 * unique canonical form. Every pathname that denotes a nonexistent file
0555 * or directory also has a unique canonical form. The canonical form of
0556 * the pathname of a nonexistent file or directory may be different from
0557 * the canonical form of the same pathname after the file or directory is
0558 * created. Similarly, the canonical form of the pathname of an existing
0559 * file or directory may be different from the canonical form of the same
0560 * pathname after the file or directory is deleted.
0561 *
0562 * @return The canonical pathname string denoting the same file or
0563 * directory as this abstract pathname
0564 *
0565 * @throws IOException
0566 * If an I/O error occurs, which is possible because the
0567 * construction of the canonical pathname may require
0568 * filesystem queries
0569 *
0570 * @throws SecurityException
0571 * If a required system property value cannot be accessed, or
0572 * if a security manager exists and its <code>{@link
0573 * java.lang.SecurityManager#checkRead}</code> method denies
0574 * read access to the file
0575 *
0576 * @since JDK1.1
0577 */
0578 public String getCanonicalPath() throws IOException {
0579 return fs.canonicalize(fs.resolve(this ));
0580 }
0581
0582 /**
0583 * Returns the canonical form of this abstract pathname. Equivalent to
0584 * <code>new File(this.{@link #getCanonicalPath})</code>.
0585 *
0586 * @return The canonical pathname string denoting the same file or
0587 * directory as this abstract pathname
0588 *
0589 * @throws IOException
0590 * If an I/O error occurs, which is possible because the
0591 * construction of the canonical pathname may require
0592 * filesystem queries
0593 *
0594 * @throws SecurityException
0595 * If a required system property value cannot be accessed, or
0596 * if a security manager exists and its <code>{@link
0597 * java.lang.SecurityManager#checkRead}</code> method denies
0598 * read access to the file
0599 *
0600 * @since 1.2
0601 */
0602 public File getCanonicalFile() throws IOException {
0603 String canonPath = getCanonicalPath();
0604 return new File(canonPath, fs.prefixLength(canonPath));
0605 }
0606
0607 private static String slashify(String path, boolean isDirectory) {
0608 String p = path;
0609 if (File.separatorChar != '/')
0610 p = p.replace(File.separatorChar, '/');
0611 if (!p.startsWith("/"))
0612 p = "/" + p;
0613 if (!p.endsWith("/") && isDirectory)
0614 p = p + "/";
0615 return p;
0616 }
0617
0618 /**
0619 * Converts this abstract pathname into a <code>file:</code> URL. The
0620 * exact form of the URL is system-dependent. If it can be determined that
0621 * the file denoted by this abstract pathname is a directory, then the
0622 * resulting URL will end with a slash.
0623 *
0624 * @return A URL object representing the equivalent file URL
0625 *
0626 * @throws MalformedURLException
0627 * If the path cannot be parsed as a URL
0628 *
0629 * @see #toURI()
0630 * @see java.net.URI
0631 * @see java.net.URI#toURL()
0632 * @see java.net.URL
0633 * @since 1.2
0634 *
0635 * @deprecated This method does not automatically escape characters that
0636 * are illegal in URLs. It is recommended that new code convert an
0637 * abstract pathname into a URL by first converting it into a URI, via the
0638 * {@link #toURI() toURI} method, and then converting the URI into a URL
0639 * via the {@link java.net.URI#toURL() URI.toURL} method.
0640 */
0641 @Deprecated
0642 public URL toURL() throws MalformedURLException {
0643 return new URL("file", "", slashify(getAbsolutePath(),
0644 isDirectory()));
0645 }
0646
0647 /**
0648 * Constructs a <tt>file:</tt> URI that represents this abstract pathname.
0649 *
0650 * <p> The exact form of the URI is system-dependent. If it can be
0651 * determined that the file denoted by this abstract pathname is a
0652 * directory, then the resulting URI will end with a slash.
0653 *
0654 * <p> For a given abstract pathname <i>f</i>, it is guaranteed that
0655 *
0656 * <blockquote><tt>
0657 * new {@link #File(java.net.URI) File}(</tt><i> f</i><tt>.toURI()).equals(</tt><i> f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
0658 * </tt></blockquote>
0659 *
0660 * so long as the original abstract pathname, the URI, and the new abstract
0661 * pathname are all created in (possibly different invocations of) the same
0662 * Java virtual machine. Due to the system-dependent nature of abstract
0663 * pathnames, however, this relationship typically does not hold when a
0664 * <tt>file:</tt> URI that is created in a virtual machine on one operating
0665 * system is converted into an abstract pathname in a virtual machine on a
0666 * different operating system.
0667 *
0668 * @return An absolute, hierarchical URI with a scheme equal to
0669 * <tt>"file"</tt>, a path representing this abstract pathname,
0670 * and undefined authority, query, and fragment components
0671 * @throws SecurityException If a required system property value cannot
0672 * be accessed.
0673 *
0674 * @see #File(java.net.URI)
0675 * @see java.net.URI
0676 * @see java.net.URI#toURL()
0677 * @since 1.4
0678 */
0679 public URI toURI() {
0680 try {
0681 File f = getAbsoluteFile();
0682 String sp = slashify(f.getPath(), f.isDirectory());
0683 if (sp.startsWith("//"))
0684 sp = "//" + sp;
0685 return new URI("file", null, sp, null);
0686 } catch (URISyntaxException x) {
0687 throw new Error(x); // Can't happen
0688 }
0689 }
0690
0691 /* -- Attribute accessors -- */
0692
0693 /**
0694 * Tests whether the application can read the file denoted by this
0695 * abstract pathname.
0696 *
0697 * @return <code>true</code> if and only if the file specified by this
0698 * abstract pathname exists <em>and</em> can be read by the
0699 * application; <code>false</code> otherwise
0700 *
0701 * @throws SecurityException
0702 * If a security manager exists and its <code>{@link
0703 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
0704 * method denies read access to the file
0705 */
0706 public boolean canRead() {
0707 SecurityManager security = System.getSecurityManager();
0708 if (security != null) {
0709 security.checkRead(path);
0710 }
0711 return fs.checkAccess(this , FileSystem.ACCESS_READ);
0712 }
0713
0714 /**
0715 * Tests whether the application can modify the file denoted by this
0716 * abstract pathname.
0717 *
0718 * @return <code>true</code> if and only if the file system actually
0719 * contains a file denoted by this abstract pathname <em>and</em>
0720 * the application is allowed to write to the file;
0721 * <code>false</code> otherwise.
0722 *
0723 * @throws SecurityException
0724 * If a security manager exists and its <code>{@link
0725 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
0726 * method denies write access to the file
0727 */
0728 public boolean canWrite() {
0729 SecurityManager security = System.getSecurityManager();
0730 if (security != null) {
0731 security.checkWrite(path);
0732 }
0733 return fs.checkAccess(this , FileSystem.ACCESS_WRITE);
0734 }
0735
0736 /**
0737 * Tests whether the file or directory denoted by this abstract pathname
0738 * exists.
0739 *
0740 * @return <code>true</code> if and only if the file or directory denoted
0741 * by this abstract pathname exists; <code>false</code> otherwise
0742 *
0743 * @throws SecurityException
0744 * If a security manager exists and its <code>{@link
0745 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
0746 * method denies read access to the file or directory
0747 */
0748 public boolean exists() {
0749 SecurityManager security = System.getSecurityManager();
0750 if (security != null) {
0751 security.checkRead(path);
0752 }
0753 return ((fs.getBooleanAttributes(this ) & FileSystem.BA_EXISTS) != 0);
0754 }
0755
0756 /**
0757 * Tests whether the file denoted by this abstract pathname is a
0758 * directory.
0759 *
0760 * @return <code>true</code> if and only if the file denoted by this
0761 * abstract pathname exists <em>and</em> is a directory;
0762 * <code>false</code> otherwise
0763 *
0764 * @throws SecurityException
0765 * If a security manager exists and its <code>{@link
0766 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
0767 * method denies read access to the file
0768 */
0769 public boolean isDirectory() {
0770 SecurityManager security = System.getSecurityManager();
0771 if (security != null) {
0772 security.checkRead(path);
0773 }
0774 return ((fs.getBooleanAttributes(this ) & FileSystem.BA_DIRECTORY) != 0);
0775 }
0776
0777 /**
0778 * Tests whether the file denoted by this abstract pathname is a normal
0779 * file. A file is <em>normal</em> if it is not a directory and, in
0780 * addition, satisfies other system-dependent criteria. Any non-directory
0781 * file created by a Java application is guaranteed to be a normal file.
0782 *
0783 * @return <code>true</code> if and only if the file denoted by this
0784 * abstract pathname exists <em>and</em> is a normal file;
0785 * <code>false</code> otherwise
0786 *
0787 * @throws SecurityException
0788 * If a security manager exists and its <code>{@link
0789 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
0790 * method denies read access to the file
0791 */
0792 public boolean isFile() {
0793 SecurityManager security = System.getSecurityManager();
0794 if (security != null) {
0795 security.checkRead(path);
0796 }
0797 return ((fs.getBooleanAttributes(this ) & FileSystem.BA_REGULAR) != 0);
0798 }
0799
0800 /**
0801 * Tests whether the file named by this abstract pathname is a hidden
0802 * file. The exact definition of <em>hidden</em> is system-dependent. On
0803 * UNIX systems, a file is considered to be hidden if its name begins with
0804 * a period character (<code>'.'</code>). On Microsoft Windows systems, a file is
0805 * considered to be hidden if it has been marked as such in the filesystem.
0806 *
0807 * @return <code>true</code> if and only if the file denoted by this
0808 * abstract pathname is hidden according to the conventions of the
0809 * underlying platform
0810 *
0811 * @throws SecurityException
0812 * If a security manager exists and its <code>{@link
0813 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
0814 * method denies read access to the file
0815 *
0816 * @since 1.2
0817 */
0818 public boolean isHidden() {
0819 SecurityManager security = System.getSecurityManager();
0820 if (security != null) {
0821 security.checkRead(path);
0822 }
0823 return ((fs.getBooleanAttributes(this ) & FileSystem.BA_HIDDEN) != 0);
0824 }
0825
0826 /**
0827 * Returns the time that the file denoted by this abstract pathname was
0828 * last modified.
0829 *
0830 * @return A <code>long</code> value representing the time the file was
0831 * last modified, measured in milliseconds since the epoch
0832 * (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
0833 * file does not exist or if an I/O error occurs
0834 *
0835 * @throws SecurityException
0836 * If a security manager exists and its <code>{@link
0837 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
0838 * method denies read access to the file
0839 */
0840 public long lastModified() {
0841 SecurityManager security = System.getSecurityManager();
0842 if (security != null) {
0843 security.checkRead(path);
0844 }
0845 return fs.getLastModifiedTime(this );
0846 }
0847
0848 /**
0849 * Returns the length of the file denoted by this abstract pathname.
0850 * The return value is unspecified if this pathname denotes a directory.
0851 *
0852 * @return The length, in bytes, of the file denoted by this abstract
0853 * pathname, or <code>0L</code> if the file does not exist. Some
0854 * operating systems may return <code>0L</code> for pathnames
0855 * denoting system-dependent entities such as devices or pipes.
0856 *
0857 * @throws SecurityException
0858 * If a security manager exists and its <code>{@link
0859 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
0860 * method denies read access to the file
0861 */
0862 public long length() {
0863 SecurityManager security = System.getSecurityManager();
0864 if (security != null) {
0865 security.checkRead(path);
0866 }
0867 return fs.getLength(this );
0868 }
0869
0870 /* -- File operations -- */
0871
0872 /**
0873 * Atomically creates a new, empty file named by this abstract pathname if
0874 * and only if a file with this name does not yet exist. The check for the
0875 * existence of the file and the creation of the file if it does not exist
0876 * are a single operation that is atomic with respect to all other
0877 * filesystem activities that might affect the file.
0878 * <P>
0879 * Note: this method should <i>not</i> be used for file-locking, as
0880 * the resulting protocol cannot be made to work reliably. The
0881 * {@link java.nio.channels.FileLock FileLock}
0882 * facility should be used instead.
0883 *
0884 * @return <code>true</code> if the named file does not exist and was
0885 * successfully created; <code>false</code> if the named file
0886 * already exists
0887 *
0888 * @throws IOException
0889 * If an I/O error occurred
0890 *
0891 * @throws SecurityException
0892 * If a security manager exists and its <code>{@link
0893 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
0894 * method denies write access to the file
0895 *
0896 * @since 1.2
0897 */
0898 public boolean createNewFile() throws IOException {
0899 SecurityManager security = System.getSecurityManager();
0900 if (security != null)
0901 security.checkWrite(path);
0902 return fs.createFileExclusively(path);
0903 }
0904
0905 /**
0906 * Deletes the file or directory denoted by this abstract pathname. If
0907 * this pathname denotes a directory, then the directory must be empty in
0908 * order to be deleted.
0909 *
0910 * @return <code>true</code> if and only if the file or directory is
0911 * successfully deleted; <code>false</code> otherwise
0912 *
0913 * @throws SecurityException
0914 * If a security manager exists and its <code>{@link
0915 * java.lang.SecurityManager#checkDelete}</code> method denies
0916 * delete access to the file
0917 */
0918 public boolean delete() {
0919 SecurityManager security = System.getSecurityManager();
0920 if (security != null) {
0921 security.checkDelete(path);
0922 }
0923 return fs.delete(this );
0924 }
0925
0926 /**
0927 * Requests that the file or directory denoted by this abstract
0928 * pathname be deleted when the virtual machine terminates.
0929 * Files (or directories) are deleted in the reverse order that
0930 * they are registered. Invoking this method to delete a file or
0931 * directory that is already registered for deletion has no effect.
0932 * Deletion will be attempted only for normal termination of the
0933 * virtual machine, as defined by the Java Language Specification.
0934 *
0935 * <p> Once deletion has been requested, it is not possible to cancel the
0936 * request. This method should therefore be used with care.
0937 *
0938 * <P>
0939 * Note: this method should <i>not</i> be used for file-locking, as
0940 * the resulting protocol cannot be made to work reliably. The
0941 * {@link java.nio.channels.FileLock FileLock}
0942 * facility should be used instead.
0943 *
0944 * @throws SecurityException
0945 * If a security manager exists and its <code>{@link
0946 * java.lang.SecurityManager#checkDelete}</code> method denies
0947 * delete access to the file
0948 *
0949 * @see #delete
0950 *
0951 * @since 1.2
0952 */
0953 public void deleteOnExit() {
0954 SecurityManager security = System.getSecurityManager();
0955 if (security != null) {
0956 security.checkDelete(path);
0957 }
0958 DeleteOnExitHook.add(path);
0959 }
0960
0961 /**
0962 * Returns an array of strings naming the files and directories in the
0963 * directory denoted by this abstract pathname.
0964 *
0965 * <p> If this abstract pathname does not denote a directory, then this
0966 * method returns {@code null}. Otherwise an array of strings is
0967 * returned, one for each file or directory in the directory. Names
0968 * denoting the directory itself and the directory's parent directory are
0969 * not included in the result. Each string is a file name rather than a
0970 * complete path.
0971 *
0972 * <p> There is no guarantee that the name strings in the resulting array
0973 * will appear in any specific order; they are not, in particular,
0974 * guaranteed to appear in alphabetical order.
0975 *
0976 * @return An array of strings naming the files and directories in the
0977 * directory denoted by this abstract pathname. The array will be
0978 * empty if the directory is empty. Returns {@code null} if
0979 * this abstract pathname does not denote a directory, or if an
0980 * I/O error occurs.
0981 *
0982 * @throws SecurityException
0983 * If a security manager exists and its {@link
0984 * SecurityManager#checkRead(String)} method denies read access to
0985 * the directory
0986 */
0987 public String[] list() {
0988 SecurityManager security = System.getSecurityManager();
0989 if (security != null) {
0990 security.checkRead(path);
0991 }
0992 return fs.list(this );
0993 }
0994
0995 /**
0996 * Returns an array of strings naming the files and directories in the
0997 * directory denoted by this abstract pathname that satisfy the specified
0998 * filter. The behavior of this method is the same as that of the
0999 * {@link #list()} method, except that the strings in the returned array
1000 * must satisfy the filter. If the given {@code filter} is {@code null}
1001 * then all names are accepted. Otherwise, a name satisfies the filter if
1002 * and only if the value {@code true} results when the {@link
1003 * FilenameFilter#accept FilenameFilter.accept(File, String)} method
1004 * of the filter is invoked on this abstract pathname and the name of a
1005 * file or directory in the directory that it denotes.
1006 *
1007 * @param filter
1008 * A filename filter
1009 *
1010 * @return An array of strings naming the files and directories in the
1011 * directory denoted by this abstract pathname that were accepted
1012 * by the given {@code filter}. The array will be empty if the
1013 * directory is empty or if no names were accepted by the filter.
1014 * Returns {@code null} if this abstract pathname does not denote
1015 * a directory, or if an I/O error occurs.
1016 *
1017 * @throws SecurityException
1018 * If a security manager exists and its {@link
1019 * SecurityManager#checkRead(String)} method denies read access to
1020 * the directory
1021 */
1022 public String[] list(FilenameFilter filter) {
1023 String names[] = list();
1024 if ((names == null) || (filter == null)) {
1025 return names;
1026 }
1027 ArrayList v = new ArrayList();
1028 for (int i = 0; i < names.length; i++) {
1029 if (filter.accept(this , names[i])) {
1030 v.add(names[i]);
1031 }
1032 }
1033 return (String[]) (v.toArray(new String[v.size()]));
1034 }
1035
1036 /**
1037 * Returns an array of abstract pathnames denoting the files in the
1038 * directory denoted by this abstract pathname.
1039 *
1040 * <p> If this abstract pathname does not denote a directory, then this
1041 * method returns {@code null}. Otherwise an array of {@code File} objects
1042 * is returned, one for each file or directory in the directory. Pathnames
1043 * denoting the directory itself and the directory's parent directory are
1044 * not included in the result. Each resulting abstract pathname is
1045 * constructed from this abstract pathname using the {@link #File(File,
1046 * String) File(File, String)} constructor. Therefore if this
1047 * pathname is absolute then each resulting pathname is absolute; if this
1048 * pathname is relative then each resulting pathname will be relative to
1049 * the same directory.
1050 *
1051 * <p> There is no guarantee that the name strings in the resulting array
1052 * will appear in any specific order; they are not, in particular,
1053 * guaranteed to appear in alphabetical order.
1054 *
1055 * @return An array of abstract pathnames denoting the files and
1056 * directories in the directory denoted by this abstract pathname.
1057 * The array will be empty if the directory is empty. Returns
1058 * {@code null} if this abstract pathname does not denote a
1059 * directory, or if an I/O error occurs.
1060 *
1061 * @throws SecurityException
1062 * If a security manager exists and its {@link
1063 * SecurityManager#checkRead(String)} method denies read access to
1064 * the directory
1065 *
1066 * @since 1.2
1067 */
1068 public File[] listFiles() {
1069 String[] ss = list();
1070 if (ss == null)
1071 return null;
1072 int n = ss.length;
1073 File[] fs = new File[n];
1074 for (int i = 0; i < n; i++) {
1075 fs[i] = new File(ss[i], this );
1076 }
1077 return fs;
1078 }
1079
1080 /**
1081 * Returns an array of abstract pathnames denoting the files and
1082 * directories in the directory denoted by this abstract pathname that
1083 * satisfy the specified filter. The behavior of this method is the same
1084 * as that of the {@link #listFiles()} method, except that the pathnames in
1085 * the returned array must satisfy the filter. If the given {@code filter}
1086 * is {@code null} then all pathnames are accepted. Otherwise, a pathname
1087 * satisfies the filter if and only if the value {@code true} results when
1088 * the {@link FilenameFilter#accept
1089 * FilenameFilter.accept(File, String)} method of the filter is
1090 * invoked on this abstract pathname and the name of a file or directory in
1091 * the directory that it denotes.
1092 *
1093 * @param filter
1094 * A filename filter
1095 *
1096 * @return An array of abstract pathnames denoting the files and
1097 * directories in the directory denoted by this abstract pathname.
1098 * The array will be empty if the directory is empty. Returns
1099 * {@code null} if this abstract pathname does not denote a
1100 * directory, or if an I/O error occurs.
1101 *
1102 * @throws SecurityException
1103 * If a security manager exists and its {@link
1104 * SecurityManager#checkRead(String)} method denies read access to
1105 * the directory
1106 *
1107 * @since 1.2
1108 */
1109 public File[] listFiles(FilenameFilter filter) {
1110 String ss[] = list();
1111 if (ss == null)
1112 return null;
1113 ArrayList<File> files = new ArrayList<File>();
1114 for (String s : ss)
1115 if ((filter == null) || filter.accept(this , s))
1116 files.add(new File(s, this ));
1117 return files.toArray(new File[files.size()]);
1118 }
1119
1120 /**
1121 * Returns an array of abstract pathnames denoting the files and
1122 * directories in the directory denoted by this abstract pathname that
1123 * satisfy the specified filter. The behavior of this method is the same
1124 * as that of the {@link #listFiles()} method, except that the pathnames in
1125 * the returned array must satisfy the filter. If the given {@code filter}
1126 * is {@code null} then all pathnames are accepted. Otherwise, a pathname
1127 * satisfies the filter if and only if the value {@code true} results when
1128 * the {@link FileFilter#accept FileFilter.accept(File)} method of the
1129 * filter is invoked on the pathname.
1130 *
1131 * @param filter
1132 * A file filter
1133 *
1134 * @return An array of abstract pathnames denoting the files and
1135 * directories in the directory denoted by this abstract pathname.
1136 * The array will be empty if the directory is empty. Returns
1137 * {@code null} if this abstract pathname does not denote a
1138 * directory, or if an I/O error occurs.
1139 *
1140 * @throws SecurityException
1141 * If a security manager exists and its {@link
1142 * SecurityManager#checkRead(String)} method denies read access to
1143 * the directory
1144 *
1145 * @since 1.2
1146 */
1147 public File[] listFiles(FileFilter filter) {
1148 String ss[] = list();
1149 if (ss == null)
1150 return null;
1151 ArrayList<File> files = new ArrayList<File>();
1152 for (String s : ss) {
1153 File f = new File(s, this );
1154 if ((filter == null) || filter.accept(f))
1155 files.add(f);
1156 }
1157 return files.toArray(new File[files.size()]);
1158 }
1159
1160 /**
1161 * Creates the directory named by this abstract pathname.
1162 *
1163 * @return <code>true</code> if and only if the directory was
1164 * created; <code>false</code> otherwise
1165 *
1166 * @throws SecurityException
1167 * If a security manager exists and its <code>{@link
1168 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1169 * method does not permit the named directory to be created
1170 */
1171 public boolean mkdir() {
1172 SecurityManager security = System.getSecurityManager();
1173 if (security != null) {
1174 security.checkWrite(path);
1175 }
1176 return fs.createDirectory(this );
1177 }
1178
1179 /**
1180 * Creates the directory named by this abstract pathname, including any
1181 * necessary but nonexistent parent directories. Note that if this
1182 * operation fails it may have succeeded in creating some of the necessary
1183 * parent directories.
1184 *
1185 * @return <code>true</code> if and only if the directory was created,
1186 * along with all necessary parent directories; <code>false</code>
1187 * otherwise
1188 *
1189 * @throws SecurityException
1190 * If a security manager exists and its <code>{@link
1191 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1192 * method does not permit verification of the existence of the
1193 * named directory and all necessary parent directories; or if
1194 * the <code>{@link
1195 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1196 * method does not permit the named directory and all necessary
1197 * parent directories to be created
1198 */
1199 public boolean mkdirs() {
1200 if (exists()) {
1201 return false;
1202 }
1203 if (mkdir()) {
1204 return true;
1205 }
1206 File canonFile = null;
1207 try {
1208 canonFile = getCanonicalFile();
1209 } catch (IOException e) {
1210 return false;
1211 }
1212
1213 File parent = canonFile.getParentFile();
1214 return (parent != null && (parent.mkdirs() || parent.exists()) && canonFile
1215 .mkdir());
1216 }
1217
1218 /**
1219 * Renames the file denoted by this abstract pathname.
1220 *
1221 * <p> Many aspects of the behavior of this method are inherently
1222 * platform-dependent: The rename operation might not be able to move a
1223 * file from one filesystem to another, it might not be atomic, and it
1224 * might not succeed if a file with the destination abstract pathname
1225 * already exists. The return value should always be checked to make sure
1226 * that the rename operation was successful.
1227 *
1228 * @param dest The new abstract pathname for the named file
1229 *
1230 * @return <code>true</code> if and only if the renaming succeeded;
1231 * <code>false</code> otherwise
1232 *
1233 * @throws SecurityException
1234 * If a security manager exists and its <code>{@link
1235 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1236 * method denies write access to either the old or new pathnames
1237 *
1238 * @throws NullPointerException
1239 * If parameter <code>dest</code> is <code>null</code>
1240 */
1241 public boolean renameTo(File dest) {
1242 SecurityManager security = System.getSecurityManager();
1243 if (security != null) {
1244 security.checkWrite(path);
1245 security.checkWrite(dest.path);
1246 }
1247 return fs.rename(this , dest);
1248 }
1249
1250 /**
1251 * Sets the last-modified time of the file or directory named by this
1252 * abstract pathname.
1253 *
1254 * <p> All platforms support file-modification times to the nearest second,
1255 * but some provide more precision. The argument will be truncated to fit
1256 * the supported precision. If the operation succeeds and no intervening
1257 * operations on the file take place, then the next invocation of the
1258 * <code>{@link #lastModified}</code> method will return the (possibly
1259 * truncated) <code>time</code> argument that was passed to this method.
1260 *
1261 * @param time The new last-modified time, measured in milliseconds since
1262 * the epoch (00:00:00 GMT, January 1, 1970)
1263 *
1264 * @return <code>true</code> if and only if the operation succeeded;
1265 * <code>false</code> otherwise
1266 *
1267 * @throws IllegalArgumentException If the argument is negative
1268 *
1269 * @throws SecurityException
1270 * If a security manager exists and its <code>{@link
1271 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1272 * method denies write access to the named file
1273 *
1274 * @since 1.2
1275 */
1276 public boolean setLastModified(long time) {
1277 if (time < 0)
1278 throw new IllegalArgumentException("Negative time");
1279 SecurityManager security = System.getSecurityManager();
1280 if (security != null) {
1281 security.checkWrite(path);
1282 }
1283 return fs.setLastModifiedTime(this , time);
1284 }
1285
1286 /**
1287 * Marks the file or directory named by this abstract pathname so that
1288 * only read operations are allowed. After invoking this method the file
1289 * or directory is guaranteed not to change until it is either deleted or
1290 * marked to allow write access. Whether or not a read-only file or
1291 * directory may be deleted depends upon the underlying system.
1292 *
1293 * @return <code>true</code> if and only if the operation succeeded;
1294 * <code>false</code> otherwise
1295 *
1296 * @throws SecurityException
1297 * If a security manager exists and its <code>{@link
1298 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1299 * method denies write access to the named file
1300 *
1301 * @since 1.2
1302 */
1303 public boolean setReadOnly() {
1304 SecurityManager security = System.getSecurityManager();
1305 if (security != null) {
1306 security.checkWrite(path);
1307 }
1308 return fs.setReadOnly(this );
1309 }
1310
1311 /**
1312 * Sets the owner's or everybody's write permission for this abstract
1313 * pathname.
1314 *
1315 * @param writable
1316 * If <code>true</code>, sets the access permission to allow write
1317 * operations; if <code>false</code> to disallow write operations
1318 *
1319 * @param ownerOnly
1320 * If <code>true</code>, the write permission applies only to the
1321 * owner's write permission; otherwise, it applies to everybody. If
1322 * the underlying file system can not distinguish the owner's write
1323 * permission from that of others, then the permission will apply to
1324 * everybody, regardless of this value.
1325 *
1326 * @return <code>true</code> if and only if the operation succeeded. The
1327 * operation will fail if the user does not have permission to change
1328 * the access permissions of this abstract pathname.
1329 *
1330 * @throws SecurityException
1331 * If a security manager exists and its <code>{@link
1332 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1333 * method denies write access to the named file
1334 *
1335 * @since 1.6
1336 */
1337 public boolean setWritable(boolean writable, boolean ownerOnly) {
1338 SecurityManager security = System.getSecurityManager();
1339 if (security != null) {
1340 security.checkWrite(path);
1341 }
1342 return fs.setPermission(this , FileSystem.ACCESS_WRITE,
1343 writable, ownerOnly);
1344 }
1345
1346 /**
1347 * A convenience method to set the owner's write permission for this abstract
1348 * pathname.
1349 *
1350 * <p> An invocation of this method of the form <tt>file.setWritable(arg)</tt>
1351 * behaves in exactly the same way as the invocation
1352 *
1353 * <pre>
1354 * file.setWritable(arg, true) </pre>
1355 *
1356 * @param writable
1357 * If <code>true</code>, sets the access permission to allow write
1358 * operations; if <code>false</code> to disallow write operations
1359 *
1360 * @return <code>true</code> if and only if the operation succeeded. The
1361 * operation will fail if the user does not have permission to
1362 * change the access permissions of this abstract pathname.
1363 *
1364 * @throws SecurityException
1365 * If a security manager exists and its <code>{@link
1366 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1367 * method denies write access to the file
1368 *
1369 * @since 1.6
1370 */
1371 public boolean setWritable(boolean writable) {
1372 return setWritable(writable, true);
1373 }
1374
1375 /**
1376 * Sets the owner's or everybody's read permission for this abstract
1377 * pathname.
1378 *
1379 * @param readable
1380 * If <code>true</code>, sets the access permission to allow read
1381 * operations; if <code>false</code> to disallow read operations
1382 *
1383 * @param ownerOnly
1384 * If <code>true</code>, the read permission applies only to the
1385 * owner's read permission; otherwise, it applies to everybody. If
1386 * the underlying file system can not distinguish the owner's read
1387 * permission from that of others, then the permission will apply to
1388 * everybody, regardless of this value.
1389 *
1390 * @return <code>true</code> if and only if the operation succeeded. The
1391 * operation will fail if the user does not have permission to
1392 * change the access permissions of this abstract pathname. If
1393 * <code>readable</code> is <code>false</code> and the underlying
1394 * file system does not implement a read permission, then the
1395 * operation will fail.
1396 *
1397 * @throws SecurityException
1398 * If a security manager exists and its <code>{@link
1399 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1400 * method denies write access to the file
1401 *
1402 * @since 1.6
1403 */
1404 public boolean setReadable(boolean readable, boolean ownerOnly) {
1405 SecurityManager security = System.getSecurityManager();
1406 if (security != null) {
1407 security.checkWrite(path);
1408 }
1409 return fs.setPermission(this , FileSystem.ACCESS_READ, readable,
1410 ownerOnly);
1411 }
1412
1413 /**
1414 * A convenience method to set the owner's read permission for this abstract
1415 * pathname.
1416 *
1417 * <p>An invocation of this method of the form <tt>file.setReadable(arg)</tt>
1418 * behaves in exactly the same way as the invocation
1419 *
1420 * <pre>
1421 * file.setReadable(arg, true) </pre>
1422 *
1423 * @param readable
1424 * If <code>true</code>, sets the access permission to allow read
1425 * operations; if <code>false</code> to disallow read operations
1426 *
1427 * @return <code>true</code> if and only if the operation succeeded. The
1428 * operation will fail if the user does not have permission to
1429 * change the access permissions of this abstract pathname. If
1430 * <code>readable</code> is <code>false</code> and the underlying
1431 * file system does not implement a read permission, then the
1432 * operation will fail.
1433 *
1434 * @throws SecurityException
1435 * If a security manager exists and its <code>{@link
1436 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1437 * method denies write access to the file
1438 *
1439 * @since 1.6
1440 */
1441 public boolean setReadable(boolean readable) {
1442 return setReadable(readable, true);
1443 }
1444
1445 /**
1446 * Sets the owner's or everybody's execute permission for this abstract
1447 * pathname.
1448 *
1449 * @param executable
1450 * If <code>true</code>, sets the access permission to allow execute
1451 * operations; if <code>false</code> to disallow execute operations
1452 *
1453 * @param ownerOnly
1454 * If <code>true</code>, the execute permission applies only to the
1455 * owner's execute permission; otherwise, it applies to everybody.
1456 * If the underlying file system can not distinguish the owner's
1457 * execute permission from that of others, then the permission will
1458 * apply to everybody, regardless of this value.
1459 *
1460 * @return <code>true</code> if and only if the operation succeeded. The
1461 * operation will fail if the user does not have permission to
1462 * change the access permissions of this abstract pathname. If
1463 * <code>executable</code> is <code>false</code> and the underlying
1464 * file system does not implement an execute permission, then the
1465 * operation will fail.
1466 *
1467 * @throws SecurityException
1468 * If a security manager exists and its <code>{@link
1469 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1470 * method denies write access to the file
1471 *
1472 * @since 1.6
1473 */
1474 public boolean setExecutable(boolean executable, boolean ownerOnly) {
1475 SecurityManager security = System.getSecurityManager();
1476 if (security != null) {
1477 security.checkWrite(path);
1478 }
1479 return fs.setPermission(this , FileSystem.ACCESS_EXECUTE,
1480 executable, ownerOnly);
1481 }
1482
1483 /**
1484 * A convenience method to set the owner's execute permission for this abstract
1485 * pathname.
1486 *
1487 * <p>An invocation of this method of the form <tt>file.setExcutable(arg)</tt>
1488 * behaves in exactly the same way as the invocation
1489 *
1490 * <pre>
1491 * file.setExecutable(arg, true) </pre>
1492 *
1493 * @param executable
1494 * If <code>true</code>, sets the access permission to allow execute
1495 * operations; if <code>false</code> to disallow execute operations
1496 *
1497 * @return <code>true</code> if and only if the operation succeeded. The
1498 * operation will fail if the user does not have permission to
1499 * change the access permissions of this abstract pathname. If
1500 * <code>executable</code> is <code>false</code> and the underlying
1501 * file system does not implement an excute permission, then the
1502 * operation will fail.
1503 *
1504 * @throws SecurityException
1505 * If a security manager exists and its <code>{@link
1506 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1507 * method denies write access to the file
1508 *
1509 * @since 1.6
1510 */
1511 public boolean setExecutable(boolean executable) {
1512 return setExecutable(executable, true);
1513 }
1514
1515 /**
1516 * Tests whether the application can execute the file denoted by this
1517 * abstract pathname.
1518 *
1519 * @return <code>true</code> if and only if the abstract pathname exists
1520 * <em>and</em> the application is allowed to execute the file
1521 *
1522 * @throws SecurityException
1523 * If a security manager exists and its <code>{@link
1524 * java.lang.SecurityManager#checkExec(java.lang.String)}</code>
1525 * method denies execute access to the file
1526 *
1527 * @since 1.6
1528 */
1529 public boolean canExecute() {
1530 SecurityManager security = System.getSecurityManager();
1531 if (security != null) {
1532 security.checkExec(path);
1533 }
1534 return fs.checkAccess(this , FileSystem.ACCESS_EXECUTE);
1535 }
1536
1537 /* -- Filesystem interface -- */
1538
1539 /**
1540 * List the available filesystem roots.
1541 *
1542 * <p> A particular Java platform may support zero or more
1543 * hierarchically-organized file systems. Each file system has a
1544 * {@code root} directory from which all other files in that file system
1545 * can be reached. Windows platforms, for example, have a root directory
1546 * for each active drive; UNIX platforms have a single root directory,
1547 * namely {@code "/"}. The set of available filesystem roots is affected
1548 * by various system-level operations such as the insertion or ejection of
1549 * removable media and the disconnecting or unmounting of physical or
1550 * virtual disk drives.
1551 *
1552 * <p> This method returns an array of {@code File} objects that denote the
1553 * root directories of the available filesystem roots. It is guaranteed
1554 * that the canonical pathname of any file physically present on the local
1555 * machine will begin with one of the roots returned by this method.
1556 *
1557 * <p> The canonical pathname of a file that resides on some other machine
1558 * and is accessed via a remote-filesystem protocol such as SMB or NFS may
1559 * or may not begin with one of the roots returned by this method. If the
1560 * pathname of a remote file is syntactically indistinguishable from the
1561 * pathname of a local file then it will begin with one of the roots
1562 * returned by this method. Thus, for example, {@code File} objects
1563 * denoting the root directories of the mapped network drives of a Windows
1564 * platform will be returned by this method, while {@code File} objects
1565 * containing UNC pathnames will not be returned by this method.
1566 *
1567 * <p> Unlike most methods in this class, this method does not throw
1568 * security exceptions. If a security manager exists and its {@link
1569 * SecurityManager#checkRead(String)} method denies read access to a
1570 * particular root directory, then that directory will not appear in the
1571 * result.
1572 *
1573 * @return An array of {@code File} objects denoting the available
1574 * filesystem roots, or {@code null} if the set of roots could not
1575 * be determined. The array will be empty if there are no
1576 * filesystem roots.
1577 *
1578 * @since 1.2
1579 */
1580 public static File[] listRoots() {
1581 return fs.listRoots();
1582 }
1583
1584 /* -- Disk usage -- */
1585
1586 /**
1587 * Returns the size of the partition <a href="#partName">named</a> by this
1588 * abstract pathname.
1589 *
1590 * @return The size, in bytes, of the partition or <tt>0L</tt> if this
1591 * abstract pathname does not name a partition
1592 *
1593 * @throws SecurityException
1594 * If a security manager has been installed and it denies
1595 * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
1596 * or its {@link SecurityManager#checkRead(String)} method denies
1597 * read access to the file named by this abstract pathname
1598 *
1599 * @since 1.6
1600 */
1601 public long getTotalSpace() {
1602 SecurityManager sm = System.getSecurityManager();
1603 if (sm != null) {
1604 sm.checkPermission(new RuntimePermission(
1605 "getFileSystemAttributes"));
1606 sm.checkRead(path);
1607 }
1608 return fs.getSpace(this , FileSystem.SPACE_TOTAL);
1609 }
1610
1611 /**
1612 * Returns the number of unallocated bytes in the partition <a
1613 * href="#partName">named</a> by this abstract path name.
1614 *
1615 * <p> The returned number of unallocated bytes is a hint, but not
1616 * a guarantee, that it is possible to use most or any of these
1617 * bytes. The number of unallocated bytes is most likely to be
1618 * accurate immediately after this call. It is likely to be made
1619 * inaccurate by any external I/O operations including those made
1620 * on the system outside of this virtual machine. This method
1621 * makes no guarantee that write operations to this file system
1622 * will succeed.
1623 *
1624 * @return The number of unallocated bytes on the partition <tt>0L</tt>
1625 * if the abstract pathname does not name a partition. This
1626 * value will be less than or equal to the total file system size
1627 * returned by {@link #getTotalSpace}.
1628 *
1629 * @throws SecurityException
1630 * If a security manager has been installed and it denies
1631 * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
1632 * or its {@link SecurityManager#checkRead(String)} method denies
1633 * read access to the file named by this abstract pathname
1634 *
1635 * @since 1.6
1636 */
1637 public long getFreeSpace() {
1638 SecurityManager sm = System.getSecurityManager();
1639 if (sm != null) {
1640 sm.checkPermission(new RuntimePermission(
1641 "getFileSystemAttributes"));
1642 sm.checkRead(path);
1643 }
1644 return fs.getSpace(this , FileSystem.SPACE_FREE);
1645 }
1646
1647 /**
1648 * Returns the number of bytes available to this virtual machine on the
1649 * partition <a href="#partName">named</a> by this abstract pathname. When
1650 * possible, this method checks for write permissions and other operating
1651 * system restrictions and will therefore usually provide a more accurate
1652 * estimate of how much new data can actually be written than {@link
1653 * #getFreeSpace}.
1654 *
1655 * <p> The returned number of available bytes is a hint, but not a
1656 * guarantee, that it is possible to use most or any of these bytes. The
1657 * number of unallocated bytes is most likely to be accurate immediately
1658 * after this call. It is likely to be made inaccurate by any external
1659 * I/O operations including those made on the system outside of this
1660 * virtual machine. This method makes no guarantee that write operations
1661 * to this file system will succeed.
1662 *
1663 * @return The number of available bytes on the partition or <tt>0L</tt>
1664 * if the abstract pathname does not name a partition. On
1665 * systems where this information is not available, this method
1666 * will be equivalent to a call to {@link #getFreeSpace}.
1667 *
1668 * @throws SecurityException
1669 * If a security manager has been installed and it denies
1670 * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
1671 * or its {@link SecurityManager#checkRead(String)} method denies
1672 * read access to the file named by this abstract pathname
1673 *
1674 * @since 1.6
1675 */
1676 public long getUsableSpace() {
1677 SecurityManager sm = System.getSecurityManager();
1678 if (sm != null) {
1679 sm.checkPermission(new RuntimePermission(
1680 "getFileSystemAttributes"));
1681 sm.checkRead(path);
1682 }
1683 return fs.getSpace(this , FileSystem.SPACE_USABLE);
1684 }
1685
1686 /* -- Temporary files -- */
1687
1688 private static final Object tmpFileLock = new Object();
1689
1690 private static int counter = -1; /* Protected by tmpFileLock */
1691
1692 private static File generateFile(String prefix, String suffix,
1693 File dir) throws IOException {
1694 if (counter == -1) {
1695 counter = new Random().nextInt() & 0xffff;
1696 }
1697 counter++;
1698 return new File(dir, prefix + Integer.toString(counter)
1699 + suffix);
1700 }
1701
1702 private static String tmpdir; /* Protected by tmpFileLock */
1703
1704 private static String getTempDir() {
1705 if (tmpdir == null) {
1706 GetPropertyAction a = new GetPropertyAction(
1707 "java.io.tmpdir");
1708 tmpdir = ((String) AccessController.doPrivileged(a));
1709 tmpdir = fs.normalize(tmpdir);
1710 }
1711 return tmpdir;
1712 }
1713
1714 private static boolean checkAndCreate(String filename,
1715 SecurityManager sm) throws IOException {
1716 if (sm != null) {
1717 try {
1718 sm.checkWrite(filename);
1719 } catch (AccessControlException x) {
1720 /* Throwing the original AccessControlException could disclose
1721 the location of the default temporary directory, so we
1722 re-throw a more innocuous SecurityException */
1723 throw new SecurityException(
1724 "Unable to create temporary file");
1725 }
1726 }
1727 return fs.createFileExclusively(filename);
1728 }
1729
1730 /**
1731 * <p> Creates a new empty file in the specified directory, using the
1732 * given prefix and suffix strings to generate its name. If this method
1733 * returns successfully then it is guaranteed that:
1734 *
1735 * <ol>
1736 * <li> The file denoted by the returned abstract pathname did not exist
1737 * before this method was invoked, and
1738 * <li> Neither this method nor any of its variants will return the same
1739 * abstract pathname again in the current invocation of the virtual
1740 * machine.
1741 * </ol>
1742 *
1743 * This method provides only part of a temporary-file facility. To arrange
1744 * for a file created by this method to be deleted automatically, use the
1745 * <code>{@link #deleteOnExit}</code> method.
1746 *
1747 * <p> The <code>prefix</code> argument must be at least three characters
1748 * long. It is recommended that the prefix be a short, meaningful string
1749 * such as <code>"hjb"</code> or <code>"mail"</code>. The
1750 * <code>suffix</code> argument may be <code>null</code>, in which case the
1751 * suffix <code>".tmp"</code> will be used.
1752 *
1753 * <p> To create the new file, the prefix and the suffix may first be
1754 * adjusted to fit the limitations of the underlying platform. If the
1755 * prefix is too long then it will be truncated, but its first three
1756 * characters will always be preserved. If the suffix is too long then it
1757 * too will be truncated, but if it begins with a period character
1758 * (<code>'.'</code>) then the period and the first three characters
1759 * following it will always be preserved. Once these adjustments have been
1760 * made the name of the new file will be generated by concatenating the
1761 * prefix, five or more internally-generated characters, and the suffix.
1762 *
1763 * <p> If the <code>directory</code> argument is <code>null</code> then the
1764 * system-dependent default temporary-file directory will be used. The
1765 * default temporary-file directory is specified by the system property
1766 * <code>java.io.tmpdir</code>. On UNIX systems the default value of this
1767 * property is typically <code>"/tmp"</code> or <code>"/var/tmp"</code>; on
1768 * Microsoft Windows systems it is typically <code>"C:\\WINNT\\TEMP"</code>. A different
1769 * value may be given to this system property when the Java virtual machine
1770 * is invoked, but programmatic changes to this property are not guaranteed
1771 * to have any effect upon the temporary directory used by this method.
1772 *
1773 * @param prefix The prefix string to be used in generating the file's
1774 * name; must be at least three characters long
1775 *
1776 * @param suffix The suffix string to be used in generating the file's
1777 * name; may be <code>null</code>, in which case the
1778 * suffix <code>".tmp"</code> will be used
1779 *
1780 * @param directory The directory in which the file is to be created, or
1781 * <code>null</code> if the default temporary-file
1782 * directory is to be used
1783 *
1784 * @return An abstract pathname denoting a newly-created empty file
1785 *
1786 * @throws IllegalArgumentException
1787 * If the <code>prefix</code> argument contains fewer than three
1788 * characters
1789 *
1790 * @throws IOException If a file could not be created
1791 *
1792 * @throws SecurityException
1793 * If a security manager exists and its <code>{@link
1794 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1795 * method does not allow a file to be created
1796 *
1797 * @since 1.2
1798 */
1799 public static File createTempFile(String prefix, String suffix,
1800 File directory) throws IOException {
1801 if (prefix == null)
1802 throw new NullPointerException();
1803 if (prefix.length() < 3)
1804 throw new IllegalArgumentException(
1805 "Prefix string too short");
1806 String s = (suffix == null) ? ".tmp" : suffix;
1807 synchronized (tmpFileLock) {
1808 if (directory == null) {
1809 String tmpDir = getTempDir();
1810 directory = new File(tmpDir, fs.prefixLength(tmpDir));
1811 }
1812 SecurityManager sm = System.getSecurityManager();
1813 File f;
1814 do {
1815 f = generateFile(prefix, s, directory);
1816 } while (!checkAndCreate(f.getPath(), sm));
1817 return f;
1818 }
1819 }
1820
1821 /**
1822 * Creates an empty file in the default temporary-file directory, using
1823 * the given prefix and suffix to generate its name. Invoking this method
1824 * is equivalent to invoking <code>{@link #createTempFile(java.lang.String,
1825 * java.lang.String, java.io.File)
1826 * createTempFile(prefix, suffix, null)}</code>.
1827 *
1828 * @param prefix The prefix string to be used in generating the file's
1829 * name; must be at least three characters long
1830 *
1831 * @param suffix The suffix string to be used in generating the file's
1832 * name; may be <code>null</code>, in which case the
1833 * suffix <code>".tmp"</code> will be used
1834 *
1835 * @return An abstract pathname denoting a newly-created empty file
1836 *
1837 * @throws IllegalArgumentException
1838 * If the <code>prefix</code> argument contains fewer than three
1839 * characters
1840 *
1841 * @throws IOException If a file could not be created
1842 *
1843 * @throws SecurityException
1844 * If a security manager exists and its <code>{@link
1845 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1846 * method does not allow a file to be created
1847 *
1848 * @since 1.2
1849 */
1850 public static File createTempFile(String prefix, String suffix)
1851 throws IOException {
1852 return createTempFile(prefix, suffix, null);
1853 }
1854
1855 /* -- Basic infrastructure -- */
1856
1857 /**
1858 * Compares two abstract pathnames lexicographically. The ordering
1859 * defined by this method depends upon the underlying system. On UNIX
1860 * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
1861 * systems it is not.
1862 *
1863 * @param pathname The abstract pathname to be compared to this abstract
1864 * pathname
1865 *
1866 * @return Zero if the argument is equal to this abstract pathname, a
1867 * value less than zero if this abstract pathname is
1868 * lexicographically less than the argument, or a value greater
1869 * than zero if this abstract pathname is lexicographically
1870 * greater than the argument
1871 *
1872 * @since 1.2
1873 */
1874 public int compareTo(File pathname) {
1875 return fs.compare(this , pathname);
1876 }
1877
1878 /**
1879 * Tests this abstract pathname for equality with the given object.
1880 * Returns <code>true</code> if and only if the argument is not
1881 * <code>null</code> and is an abstract pathname that denotes the same file
1882 * or directory as this abstract pathname. Whether or not two abstract
1883 * pathnames are equal depends upon the underlying system. On UNIX
1884 * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
1885 * systems it is not.
1886 *
1887 * @param obj The object to be compared with this abstract pathname
1888 *
1889 * @return <code>true</code> if and only if the objects are the same;
1890 * <code>false</code> otherwise
1891 */
1892 public boolean equals(Object obj) {
1893 if ((obj != null) && (obj instanceof File)) {
1894 return compareTo((File) obj) == 0;
1895 }
1896 return false;
1897 }
1898
1899 /**
1900 * Computes a hash code for this abstract pathname. Because equality of
1901 * abstract pathnames is inherently system-dependent, so is the computation
1902 * of their hash codes. On UNIX systems, the hash code of an abstract
1903 * pathname is equal to the exclusive <em>or</em> of the hash code
1904 * of its pathname string and the decimal value
1905 * <code>1234321</code>. On Microsoft Windows systems, the hash
1906 * code is equal to the exclusive <em>or</em> of the hash code of
1907 * its pathname string converted to lower case and the decimal
1908 * value <code>1234321</code>. Locale is not taken into account on
1909 * lowercasing the pathname string.
1910 *
1911 * @return A hash code for this abstract pathname
1912 */
1913 public int hashCode() {
1914 return fs.hashCode(this );
1915 }
1916
1917 /**
1918 * Returns the pathname string of this abstract pathname. This is just the
1919 * string returned by the <code>{@link #getPath}</code> method.
1920 *
1921 * @return The string form of this abstract pathname
1922 */
1923 public String toString() {
1924 return getPath();
1925 }
1926
1927 /**
1928 * WriteObject is called to save this filename.
1929 * The separator character is saved also so it can be replaced
1930 * in case the path is reconstituted on a different host type.
1931 * <p>
1932 * @serialData Default fields followed by separator character.
1933 */
1934 private synchronized void writeObject(java.io.ObjectOutputStream s)
1935 throws IOException {
1936 s.defaultWriteObject();
1937 s.writeChar(this .separatorChar); // Add the separator character
1938 }
1939
1940 /**
1941 * readObject is called to restore this filename.
1942 * The original separator character is read. If it is different
1943 * than the separator character on this system, then the old separator
1944 * is replaced by the local separator.
1945 */
1946 private synchronized void readObject(java.io.ObjectInputStream s)
1947 throws IOException, ClassNotFoundException {
1948 s.defaultReadObject();
1949 char sep = s.readChar(); // read the previous separator char
1950 if (sep != separatorChar)
1951 this .path = this .path.replace(sep, separatorChar);
1952 this .path = fs.normalize(this .path);
1953 this .prefixLength = fs.prefixLength(this .path);
1954 }
1955
1956 /** use serialVersionUID from JDK 1.0.2 for interoperability */
1957 private static final long serialVersionUID = 301077366599181567L;
1958
1959 // Set up JavaIODeleteOnExitAccess in SharedSecrets
1960 // Added here as DeleteOnExitHook is package-private and SharedSecrets cannot easily access it.
1961 static {
1962 sun.misc.SharedSecrets
1963 .setJavaIODeleteOnExitAccess(new sun.misc.JavaIODeleteOnExitAccess() {
1964 public void run() {
1965 DeleteOnExitHook.hook().run();
1966 }
1967 });
1968 }
1969
1970 }
|