1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/emul/compact/src/main/java/java/io/File.java Sat Sep 07 13:51:24 2013 +0200
1.3 @@ -0,0 +1,2076 @@
1.4 +/*
1.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.io;
1.30 +
1.31 +import java.net.URI;
1.32 +import java.net.URL;
1.33 +import java.net.MalformedURLException;
1.34 +import java.net.URISyntaxException;
1.35 +import java.util.List;
1.36 +import java.util.ArrayList;
1.37 +import java.security.AccessController;
1.38 +import java.security.SecureRandom;
1.39 +import java.nio.file.Path;
1.40 +import java.nio.file.FileSystems;
1.41 +import sun.security.action.GetPropertyAction;
1.42 +
1.43 +/**
1.44 + * An abstract representation of file and directory pathnames.
1.45 + *
1.46 + * <p> User interfaces and operating systems use system-dependent <em>pathname
1.47 + * strings</em> to name files and directories. This class presents an
1.48 + * abstract, system-independent view of hierarchical pathnames. An
1.49 + * <em>abstract pathname</em> has two components:
1.50 + *
1.51 + * <ol>
1.52 + * <li> An optional system-dependent <em>prefix</em> string,
1.53 + * such as a disk-drive specifier, <code>"/"</code> for the UNIX root
1.54 + * directory, or <code>"\\\\"</code> for a Microsoft Windows UNC pathname, and
1.55 + * <li> A sequence of zero or more string <em>names</em>.
1.56 + * </ol>
1.57 + *
1.58 + * The first name in an abstract pathname may be a directory name or, in the
1.59 + * case of Microsoft Windows UNC pathnames, a hostname. Each subsequent name
1.60 + * in an abstract pathname denotes a directory; the last name may denote
1.61 + * either a directory or a file. The <em>empty</em> abstract pathname has no
1.62 + * prefix and an empty name sequence.
1.63 + *
1.64 + * <p> The conversion of a pathname string to or from an abstract pathname is
1.65 + * inherently system-dependent. When an abstract pathname is converted into a
1.66 + * pathname string, each name is separated from the next by a single copy of
1.67 + * the default <em>separator character</em>. The default name-separator
1.68 + * character is defined by the system property <code>file.separator</code>, and
1.69 + * is made available in the public static fields <code>{@link
1.70 + * #separator}</code> and <code>{@link #separatorChar}</code> of this class.
1.71 + * When a pathname string is converted into an abstract pathname, the names
1.72 + * within it may be separated by the default name-separator character or by any
1.73 + * other name-separator character that is supported by the underlying system.
1.74 + *
1.75 + * <p> A pathname, whether abstract or in string form, may be either
1.76 + * <em>absolute</em> or <em>relative</em>. An absolute pathname is complete in
1.77 + * that no other information is required in order to locate the file that it
1.78 + * denotes. A relative pathname, in contrast, must be interpreted in terms of
1.79 + * information taken from some other pathname. By default the classes in the
1.80 + * <code>java.io</code> package always resolve relative pathnames against the
1.81 + * current user directory. This directory is named by the system property
1.82 + * <code>user.dir</code>, and is typically the directory in which the Java
1.83 + * virtual machine was invoked.
1.84 + *
1.85 + * <p> The <em>parent</em> of an abstract pathname may be obtained by invoking
1.86 + * the {@link #getParent} method of this class and consists of the pathname's
1.87 + * prefix and each name in the pathname's name sequence except for the last.
1.88 + * Each directory's absolute pathname is an ancestor of any <tt>File</tt>
1.89 + * object with an absolute abstract pathname which begins with the directory's
1.90 + * absolute pathname. For example, the directory denoted by the abstract
1.91 + * pathname <tt>"/usr"</tt> is an ancestor of the directory denoted by the
1.92 + * pathname <tt>"/usr/local/bin"</tt>.
1.93 + *
1.94 + * <p> The prefix concept is used to handle root directories on UNIX platforms,
1.95 + * and drive specifiers, root directories and UNC pathnames on Microsoft Windows platforms,
1.96 + * as follows:
1.97 + *
1.98 + * <ul>
1.99 + *
1.100 + * <li> For UNIX platforms, the prefix of an absolute pathname is always
1.101 + * <code>"/"</code>. Relative pathnames have no prefix. The abstract pathname
1.102 + * denoting the root directory has the prefix <code>"/"</code> and an empty
1.103 + * name sequence.
1.104 + *
1.105 + * <li> For Microsoft Windows platforms, the prefix of a pathname that contains a drive
1.106 + * specifier consists of the drive letter followed by <code>":"</code> and
1.107 + * possibly followed by <code>"\\"</code> if the pathname is absolute. The
1.108 + * prefix of a UNC pathname is <code>"\\\\"</code>; the hostname and the share
1.109 + * name are the first two names in the name sequence. A relative pathname that
1.110 + * does not specify a drive has no prefix.
1.111 + *
1.112 + * </ul>
1.113 + *
1.114 + * <p> Instances of this class may or may not denote an actual file-system
1.115 + * object such as a file or a directory. If it does denote such an object
1.116 + * then that object resides in a <i>partition</i>. A partition is an
1.117 + * operating system-specific portion of storage for a file system. A single
1.118 + * storage device (e.g. a physical disk-drive, flash memory, CD-ROM) may
1.119 + * contain multiple partitions. The object, if any, will reside on the
1.120 + * partition <a name="partName">named</a> by some ancestor of the absolute
1.121 + * form of this pathname.
1.122 + *
1.123 + * <p> A file system may implement restrictions to certain operations on the
1.124 + * actual file-system object, such as reading, writing, and executing. These
1.125 + * restrictions are collectively known as <i>access permissions</i>. The file
1.126 + * system may have multiple sets of access permissions on a single object.
1.127 + * For example, one set may apply to the object's <i>owner</i>, and another
1.128 + * may apply to all other users. The access permissions on an object may
1.129 + * cause some methods in this class to fail.
1.130 + *
1.131 + * <p> Instances of the <code>File</code> class are immutable; that is, once
1.132 + * created, the abstract pathname represented by a <code>File</code> object
1.133 + * will never change.
1.134 + *
1.135 + * <h4>Interoperability with {@code java.nio.file} package</h4>
1.136 + *
1.137 + * <p> The <a href="../../java/nio/file/package-summary.html">{@code java.nio.file}</a>
1.138 + * package defines interfaces and classes for the Java virtual machine to access
1.139 + * files, file attributes, and file systems. This API may be used to overcome
1.140 + * many of the limitations of the {@code java.io.File} class.
1.141 + * The {@link #toPath toPath} method may be used to obtain a {@link
1.142 + * Path} that uses the abstract path represented by a {@code File} object to
1.143 + * locate a file. The resulting {@code Path} may be used with the {@link
1.144 + * java.nio.file.Files} class to provide more efficient and extensive access to
1.145 + * additional file operations, file attributes, and I/O exceptions to help
1.146 + * diagnose errors when an operation on a file fails.
1.147 + *
1.148 + * @author unascribed
1.149 + * @since JDK1.0
1.150 + */
1.151 +
1.152 +public class File
1.153 + implements Serializable, Comparable<File>
1.154 +{
1.155 +
1.156 + /**
1.157 + * The FileSystem object representing the platform's local file system.
1.158 + */
1.159 + static private FileSystem fs = FileSystem.getFileSystem();
1.160 +
1.161 + /**
1.162 + * This abstract pathname's normalized pathname string. A normalized
1.163 + * pathname string uses the default name-separator character and does not
1.164 + * contain any duplicate or redundant separators.
1.165 + *
1.166 + * @serial
1.167 + */
1.168 + private String path;
1.169 +
1.170 + /**
1.171 + * The length of this abstract pathname's prefix, or zero if it has no
1.172 + * prefix.
1.173 + */
1.174 + private transient int prefixLength;
1.175 +
1.176 + /**
1.177 + * Returns the length of this abstract pathname's prefix.
1.178 + * For use by FileSystem classes.
1.179 + */
1.180 + int getPrefixLength() {
1.181 + return prefixLength;
1.182 + }
1.183 +
1.184 + /**
1.185 + * The system-dependent default name-separator character. This field is
1.186 + * initialized to contain the first character of the value of the system
1.187 + * property <code>file.separator</code>. On UNIX systems the value of this
1.188 + * field is <code>'/'</code>; on Microsoft Windows systems it is <code>'\\'</code>.
1.189 + *
1.190 + * @see java.lang.System#getProperty(java.lang.String)
1.191 + */
1.192 + public static final char separatorChar = fs.getSeparator();
1.193 +
1.194 + /**
1.195 + * The system-dependent default name-separator character, represented as a
1.196 + * string for convenience. This string contains a single character, namely
1.197 + * <code>{@link #separatorChar}</code>.
1.198 + */
1.199 + public static final String separator = "" + separatorChar;
1.200 +
1.201 + /**
1.202 + * The system-dependent path-separator character. This field is
1.203 + * initialized to contain the first character of the value of the system
1.204 + * property <code>path.separator</code>. This character is used to
1.205 + * separate filenames in a sequence of files given as a <em>path list</em>.
1.206 + * On UNIX systems, this character is <code>':'</code>; on Microsoft Windows systems it
1.207 + * is <code>';'</code>.
1.208 + *
1.209 + * @see java.lang.System#getProperty(java.lang.String)
1.210 + */
1.211 + public static final char pathSeparatorChar = fs.getPathSeparator();
1.212 +
1.213 + /**
1.214 + * The system-dependent path-separator character, represented as a string
1.215 + * for convenience. This string contains a single character, namely
1.216 + * <code>{@link #pathSeparatorChar}</code>.
1.217 + */
1.218 + public static final String pathSeparator = "" + pathSeparatorChar;
1.219 +
1.220 +
1.221 + /* -- Constructors -- */
1.222 +
1.223 + /**
1.224 + * Internal constructor for already-normalized pathname strings.
1.225 + */
1.226 + private File(String pathname, int prefixLength) {
1.227 + this.path = pathname;
1.228 + this.prefixLength = prefixLength;
1.229 + }
1.230 +
1.231 + /**
1.232 + * Internal constructor for already-normalized pathname strings.
1.233 + * The parameter order is used to disambiguate this method from the
1.234 + * public(File, String) constructor.
1.235 + */
1.236 + private File(String child, File parent) {
1.237 + assert parent.path != null;
1.238 + assert (!parent.path.equals(""));
1.239 + this.path = fs.resolve(parent.path, child);
1.240 + this.prefixLength = parent.prefixLength;
1.241 + }
1.242 +
1.243 + /**
1.244 + * Creates a new <code>File</code> instance by converting the given
1.245 + * pathname string into an abstract pathname. If the given string is
1.246 + * the empty string, then the result is the empty abstract pathname.
1.247 + *
1.248 + * @param pathname A pathname string
1.249 + * @throws NullPointerException
1.250 + * If the <code>pathname</code> argument is <code>null</code>
1.251 + */
1.252 + public File(String pathname) {
1.253 + if (pathname == null) {
1.254 + throw new NullPointerException();
1.255 + }
1.256 + this.path = fs.normalize(pathname);
1.257 + this.prefixLength = fs.prefixLength(this.path);
1.258 + }
1.259 +
1.260 + /* Note: The two-argument File constructors do not interpret an empty
1.261 + parent abstract pathname as the current user directory. An empty parent
1.262 + instead causes the child to be resolved against the system-dependent
1.263 + directory defined by the FileSystem.getDefaultParent method. On Unix
1.264 + this default is "/", while on Microsoft Windows it is "\\". This is required for
1.265 + compatibility with the original behavior of this class. */
1.266 +
1.267 + /**
1.268 + * Creates a new <code>File</code> instance from a parent pathname string
1.269 + * and a child pathname string.
1.270 + *
1.271 + * <p> If <code>parent</code> is <code>null</code> then the new
1.272 + * <code>File</code> instance is created as if by invoking the
1.273 + * single-argument <code>File</code> constructor on the given
1.274 + * <code>child</code> pathname string.
1.275 + *
1.276 + * <p> Otherwise the <code>parent</code> pathname string is taken to denote
1.277 + * a directory, and the <code>child</code> pathname string is taken to
1.278 + * denote either a directory or a file. If the <code>child</code> pathname
1.279 + * string is absolute then it is converted into a relative pathname in a
1.280 + * system-dependent way. If <code>parent</code> is the empty string then
1.281 + * the new <code>File</code> instance is created by converting
1.282 + * <code>child</code> into an abstract pathname and resolving the result
1.283 + * against a system-dependent default directory. Otherwise each pathname
1.284 + * string is converted into an abstract pathname and the child abstract
1.285 + * pathname is resolved against the parent.
1.286 + *
1.287 + * @param parent The parent pathname string
1.288 + * @param child The child pathname string
1.289 + * @throws NullPointerException
1.290 + * If <code>child</code> is <code>null</code>
1.291 + */
1.292 + public File(String parent, String child) {
1.293 + if (child == null) {
1.294 + throw new NullPointerException();
1.295 + }
1.296 + if (parent != null) {
1.297 + if (parent.equals("")) {
1.298 + this.path = fs.resolve(fs.getDefaultParent(),
1.299 + fs.normalize(child));
1.300 + } else {
1.301 + this.path = fs.resolve(fs.normalize(parent),
1.302 + fs.normalize(child));
1.303 + }
1.304 + } else {
1.305 + this.path = fs.normalize(child);
1.306 + }
1.307 + this.prefixLength = fs.prefixLength(this.path);
1.308 + }
1.309 +
1.310 + /**
1.311 + * Creates a new <code>File</code> instance from a parent abstract
1.312 + * pathname and a child pathname string.
1.313 + *
1.314 + * <p> If <code>parent</code> is <code>null</code> then the new
1.315 + * <code>File</code> instance is created as if by invoking the
1.316 + * single-argument <code>File</code> constructor on the given
1.317 + * <code>child</code> pathname string.
1.318 + *
1.319 + * <p> Otherwise the <code>parent</code> abstract pathname is taken to
1.320 + * denote a directory, and the <code>child</code> pathname string is taken
1.321 + * to denote either a directory or a file. If the <code>child</code>
1.322 + * pathname string is absolute then it is converted into a relative
1.323 + * pathname in a system-dependent way. If <code>parent</code> is the empty
1.324 + * abstract pathname then the new <code>File</code> instance is created by
1.325 + * converting <code>child</code> into an abstract pathname and resolving
1.326 + * the result against a system-dependent default directory. Otherwise each
1.327 + * pathname string is converted into an abstract pathname and the child
1.328 + * abstract pathname is resolved against the parent.
1.329 + *
1.330 + * @param parent The parent abstract pathname
1.331 + * @param child The child pathname string
1.332 + * @throws NullPointerException
1.333 + * If <code>child</code> is <code>null</code>
1.334 + */
1.335 + public File(File parent, String child) {
1.336 + if (child == null) {
1.337 + throw new NullPointerException();
1.338 + }
1.339 + if (parent != null) {
1.340 + if (parent.path.equals("")) {
1.341 + this.path = fs.resolve(fs.getDefaultParent(),
1.342 + fs.normalize(child));
1.343 + } else {
1.344 + this.path = fs.resolve(parent.path,
1.345 + fs.normalize(child));
1.346 + }
1.347 + } else {
1.348 + this.path = fs.normalize(child);
1.349 + }
1.350 + this.prefixLength = fs.prefixLength(this.path);
1.351 + }
1.352 +
1.353 + /**
1.354 + * Creates a new <tt>File</tt> instance by converting the given
1.355 + * <tt>file:</tt> URI into an abstract pathname.
1.356 + *
1.357 + * <p> The exact form of a <tt>file:</tt> URI is system-dependent, hence
1.358 + * the transformation performed by this constructor is also
1.359 + * system-dependent.
1.360 + *
1.361 + * <p> For a given abstract pathname <i>f</i> it is guaranteed that
1.362 + *
1.363 + * <blockquote><tt>
1.364 + * new File(</tt><i> f</i><tt>.{@link #toURI() toURI}()).equals(</tt><i> f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
1.365 + * </tt></blockquote>
1.366 + *
1.367 + * so long as the original abstract pathname, the URI, and the new abstract
1.368 + * pathname are all created in (possibly different invocations of) the same
1.369 + * Java virtual machine. This relationship typically does not hold,
1.370 + * however, when a <tt>file:</tt> URI that is created in a virtual machine
1.371 + * on one operating system is converted into an abstract pathname in a
1.372 + * virtual machine on a different operating system.
1.373 + *
1.374 + * @param uri
1.375 + * An absolute, hierarchical URI with a scheme equal to
1.376 + * <tt>"file"</tt>, a non-empty path component, and undefined
1.377 + * authority, query, and fragment components
1.378 + *
1.379 + * @throws NullPointerException
1.380 + * If <tt>uri</tt> is <tt>null</tt>
1.381 + *
1.382 + * @throws IllegalArgumentException
1.383 + * If the preconditions on the parameter do not hold
1.384 + *
1.385 + * @see #toURI()
1.386 + * @see java.net.URI
1.387 + * @since 1.4
1.388 + */
1.389 + public File(URI uri) {
1.390 +
1.391 + // Check our many preconditions
1.392 + if (!uri.isAbsolute())
1.393 + throw new IllegalArgumentException("URI is not absolute");
1.394 + if (uri.isOpaque())
1.395 + throw new IllegalArgumentException("URI is not hierarchical");
1.396 + String scheme = uri.getScheme();
1.397 + if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
1.398 + throw new IllegalArgumentException("URI scheme is not \"file\"");
1.399 + if (uri.getAuthority() != null)
1.400 + throw new IllegalArgumentException("URI has an authority component");
1.401 + if (uri.getFragment() != null)
1.402 + throw new IllegalArgumentException("URI has a fragment component");
1.403 + if (uri.getQuery() != null)
1.404 + throw new IllegalArgumentException("URI has a query component");
1.405 + String p = uri.getPath();
1.406 + if (p.equals(""))
1.407 + throw new IllegalArgumentException("URI path component is empty");
1.408 +
1.409 + // Okay, now initialize
1.410 + p = fs.fromURIPath(p);
1.411 + if (File.separatorChar != '/')
1.412 + p = p.replace('/', File.separatorChar);
1.413 + this.path = fs.normalize(p);
1.414 + this.prefixLength = fs.prefixLength(this.path);
1.415 + }
1.416 +
1.417 +
1.418 + /* -- Path-component accessors -- */
1.419 +
1.420 + /**
1.421 + * Returns the name of the file or directory denoted by this abstract
1.422 + * pathname. This is just the last name in the pathname's name
1.423 + * sequence. If the pathname's name sequence is empty, then the empty
1.424 + * string is returned.
1.425 + *
1.426 + * @return The name of the file or directory denoted by this abstract
1.427 + * pathname, or the empty string if this pathname's name sequence
1.428 + * is empty
1.429 + */
1.430 + public String getName() {
1.431 + int index = path.lastIndexOf(separatorChar);
1.432 + if (index < prefixLength) return path.substring(prefixLength);
1.433 + return path.substring(index + 1);
1.434 + }
1.435 +
1.436 + /**
1.437 + * Returns the pathname string of this abstract pathname's parent, or
1.438 + * <code>null</code> if this pathname does not name a parent directory.
1.439 + *
1.440 + * <p> The <em>parent</em> of an abstract pathname consists of the
1.441 + * pathname's prefix, if any, and each name in the pathname's name
1.442 + * sequence except for the last. If the name sequence is empty then
1.443 + * the pathname does not name a parent directory.
1.444 + *
1.445 + * @return The pathname string of the parent directory named by this
1.446 + * abstract pathname, or <code>null</code> if this pathname
1.447 + * does not name a parent
1.448 + */
1.449 + public String getParent() {
1.450 + int index = path.lastIndexOf(separatorChar);
1.451 + if (index < prefixLength) {
1.452 + if ((prefixLength > 0) && (path.length() > prefixLength))
1.453 + return path.substring(0, prefixLength);
1.454 + return null;
1.455 + }
1.456 + return path.substring(0, index);
1.457 + }
1.458 +
1.459 + /**
1.460 + * Returns the abstract pathname of this abstract pathname's parent,
1.461 + * or <code>null</code> if this pathname does not name a parent
1.462 + * directory.
1.463 + *
1.464 + * <p> The <em>parent</em> of an abstract pathname consists of the
1.465 + * pathname's prefix, if any, and each name in the pathname's name
1.466 + * sequence except for the last. If the name sequence is empty then
1.467 + * the pathname does not name a parent directory.
1.468 + *
1.469 + * @return The abstract pathname of the parent directory named by this
1.470 + * abstract pathname, or <code>null</code> if this pathname
1.471 + * does not name a parent
1.472 + *
1.473 + * @since 1.2
1.474 + */
1.475 + public File getParentFile() {
1.476 + String p = this.getParent();
1.477 + if (p == null) return null;
1.478 + return new File(p, this.prefixLength);
1.479 + }
1.480 +
1.481 + /**
1.482 + * Converts this abstract pathname into a pathname string. The resulting
1.483 + * string uses the {@link #separator default name-separator character} to
1.484 + * separate the names in the name sequence.
1.485 + *
1.486 + * @return The string form of this abstract pathname
1.487 + */
1.488 + public String getPath() {
1.489 + return path;
1.490 + }
1.491 +
1.492 +
1.493 + /* -- Path operations -- */
1.494 +
1.495 + /**
1.496 + * Tests whether this abstract pathname is absolute. The definition of
1.497 + * absolute pathname is system dependent. On UNIX systems, a pathname is
1.498 + * absolute if its prefix is <code>"/"</code>. On Microsoft Windows systems, a
1.499 + * pathname is absolute if its prefix is a drive specifier followed by
1.500 + * <code>"\\"</code>, or if its prefix is <code>"\\\\"</code>.
1.501 + *
1.502 + * @return <code>true</code> if this abstract pathname is absolute,
1.503 + * <code>false</code> otherwise
1.504 + */
1.505 + public boolean isAbsolute() {
1.506 + return fs.isAbsolute(this);
1.507 + }
1.508 +
1.509 + /**
1.510 + * Returns the absolute pathname string of this abstract pathname.
1.511 + *
1.512 + * <p> If this abstract pathname is already absolute, then the pathname
1.513 + * string is simply returned as if by the <code>{@link #getPath}</code>
1.514 + * method. If this abstract pathname is the empty abstract pathname then
1.515 + * the pathname string of the current user directory, which is named by the
1.516 + * system property <code>user.dir</code>, is returned. Otherwise this
1.517 + * pathname is resolved in a system-dependent way. On UNIX systems, a
1.518 + * relative pathname is made absolute by resolving it against the current
1.519 + * user directory. On Microsoft Windows systems, a relative pathname is made absolute
1.520 + * by resolving it against the current directory of the drive named by the
1.521 + * pathname, if any; if not, it is resolved against the current user
1.522 + * directory.
1.523 + *
1.524 + * @return The absolute pathname string denoting the same file or
1.525 + * directory as this abstract pathname
1.526 + *
1.527 + * @throws SecurityException
1.528 + * If a required system property value cannot be accessed.
1.529 + *
1.530 + * @see java.io.File#isAbsolute()
1.531 + */
1.532 + public String getAbsolutePath() {
1.533 + return fs.resolve(this);
1.534 + }
1.535 +
1.536 + /**
1.537 + * Returns the absolute form of this abstract pathname. Equivalent to
1.538 + * <code>new File(this.{@link #getAbsolutePath})</code>.
1.539 + *
1.540 + * @return The absolute abstract pathname denoting the same file or
1.541 + * directory as this abstract pathname
1.542 + *
1.543 + * @throws SecurityException
1.544 + * If a required system property value cannot be accessed.
1.545 + *
1.546 + * @since 1.2
1.547 + */
1.548 + public File getAbsoluteFile() {
1.549 + String absPath = getAbsolutePath();
1.550 + return new File(absPath, fs.prefixLength(absPath));
1.551 + }
1.552 +
1.553 + /**
1.554 + * Returns the canonical pathname string of this abstract pathname.
1.555 + *
1.556 + * <p> A canonical pathname is both absolute and unique. The precise
1.557 + * definition of canonical form is system-dependent. This method first
1.558 + * converts this pathname to absolute form if necessary, as if by invoking the
1.559 + * {@link #getAbsolutePath} method, and then maps it to its unique form in a
1.560 + * system-dependent way. This typically involves removing redundant names
1.561 + * such as <tt>"."</tt> and <tt>".."</tt> from the pathname, resolving
1.562 + * symbolic links (on UNIX platforms), and converting drive letters to a
1.563 + * standard case (on Microsoft Windows platforms).
1.564 + *
1.565 + * <p> Every pathname that denotes an existing file or directory has a
1.566 + * unique canonical form. Every pathname that denotes a nonexistent file
1.567 + * or directory also has a unique canonical form. The canonical form of
1.568 + * the pathname of a nonexistent file or directory may be different from
1.569 + * the canonical form of the same pathname after the file or directory is
1.570 + * created. Similarly, the canonical form of the pathname of an existing
1.571 + * file or directory may be different from the canonical form of the same
1.572 + * pathname after the file or directory is deleted.
1.573 + *
1.574 + * @return The canonical pathname string denoting the same file or
1.575 + * directory as this abstract pathname
1.576 + *
1.577 + * @throws IOException
1.578 + * If an I/O error occurs, which is possible because the
1.579 + * construction of the canonical pathname may require
1.580 + * filesystem queries
1.581 + *
1.582 + * @throws SecurityException
1.583 + * If a required system property value cannot be accessed, or
1.584 + * if a security manager exists and its <code>{@link
1.585 + * java.lang.SecurityManager#checkRead}</code> method denies
1.586 + * read access to the file
1.587 + *
1.588 + * @since JDK1.1
1.589 + * @see Path#toRealPath
1.590 + */
1.591 + public String getCanonicalPath() throws IOException {
1.592 + return fs.canonicalize(fs.resolve(this));
1.593 + }
1.594 +
1.595 + /**
1.596 + * Returns the canonical form of this abstract pathname. Equivalent to
1.597 + * <code>new File(this.{@link #getCanonicalPath})</code>.
1.598 + *
1.599 + * @return The canonical pathname string denoting the same file or
1.600 + * directory as this abstract pathname
1.601 + *
1.602 + * @throws IOException
1.603 + * If an I/O error occurs, which is possible because the
1.604 + * construction of the canonical pathname may require
1.605 + * filesystem queries
1.606 + *
1.607 + * @throws SecurityException
1.608 + * If a required system property value cannot be accessed, or
1.609 + * if a security manager exists and its <code>{@link
1.610 + * java.lang.SecurityManager#checkRead}</code> method denies
1.611 + * read access to the file
1.612 + *
1.613 + * @since 1.2
1.614 + * @see Path#toRealPath
1.615 + */
1.616 + public File getCanonicalFile() throws IOException {
1.617 + String canonPath = getCanonicalPath();
1.618 + return new File(canonPath, fs.prefixLength(canonPath));
1.619 + }
1.620 +
1.621 + private static String slashify(String path, boolean isDirectory) {
1.622 + String p = path;
1.623 + if (File.separatorChar != '/')
1.624 + p = p.replace(File.separatorChar, '/');
1.625 + if (!p.startsWith("/"))
1.626 + p = "/" + p;
1.627 + if (!p.endsWith("/") && isDirectory)
1.628 + p = p + "/";
1.629 + return p;
1.630 + }
1.631 +
1.632 + /**
1.633 + * Converts this abstract pathname into a <code>file:</code> URL. The
1.634 + * exact form of the URL is system-dependent. If it can be determined that
1.635 + * the file denoted by this abstract pathname is a directory, then the
1.636 + * resulting URL will end with a slash.
1.637 + *
1.638 + * @return A URL object representing the equivalent file URL
1.639 + *
1.640 + * @throws MalformedURLException
1.641 + * If the path cannot be parsed as a URL
1.642 + *
1.643 + * @see #toURI()
1.644 + * @see java.net.URI
1.645 + * @see java.net.URI#toURL()
1.646 + * @see java.net.URL
1.647 + * @since 1.2
1.648 + *
1.649 + * @deprecated This method does not automatically escape characters that
1.650 + * are illegal in URLs. It is recommended that new code convert an
1.651 + * abstract pathname into a URL by first converting it into a URI, via the
1.652 + * {@link #toURI() toURI} method, and then converting the URI into a URL
1.653 + * via the {@link java.net.URI#toURL() URI.toURL} method.
1.654 + */
1.655 + @Deprecated
1.656 + public URL toURL() throws MalformedURLException {
1.657 + return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
1.658 + }
1.659 +
1.660 + /**
1.661 + * Constructs a <tt>file:</tt> URI that represents this abstract pathname.
1.662 + *
1.663 + * <p> The exact form of the URI is system-dependent. If it can be
1.664 + * determined that the file denoted by this abstract pathname is a
1.665 + * directory, then the resulting URI will end with a slash.
1.666 + *
1.667 + * <p> For a given abstract pathname <i>f</i>, it is guaranteed that
1.668 + *
1.669 + * <blockquote><tt>
1.670 + * new {@link #File(java.net.URI) File}(</tt><i> f</i><tt>.toURI()).equals(</tt><i> f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
1.671 + * </tt></blockquote>
1.672 + *
1.673 + * so long as the original abstract pathname, the URI, and the new abstract
1.674 + * pathname are all created in (possibly different invocations of) the same
1.675 + * Java virtual machine. Due to the system-dependent nature of abstract
1.676 + * pathnames, however, this relationship typically does not hold when a
1.677 + * <tt>file:</tt> URI that is created in a virtual machine on one operating
1.678 + * system is converted into an abstract pathname in a virtual machine on a
1.679 + * different operating system.
1.680 + *
1.681 + * <p> Note that when this abstract pathname represents a UNC pathname then
1.682 + * all components of the UNC (including the server name component) are encoded
1.683 + * in the {@code URI} path. The authority component is undefined, meaning
1.684 + * that it is represented as {@code null}. The {@link Path} class defines the
1.685 + * {@link Path#toUri toUri} method to encode the server name in the authority
1.686 + * component of the resulting {@code URI}. The {@link #toPath toPath} method
1.687 + * may be used to obtain a {@code Path} representing this abstract pathname.
1.688 + *
1.689 + * @return An absolute, hierarchical URI with a scheme equal to
1.690 + * <tt>"file"</tt>, a path representing this abstract pathname,
1.691 + * and undefined authority, query, and fragment components
1.692 + * @throws SecurityException If a required system property value cannot
1.693 + * be accessed.
1.694 + *
1.695 + * @see #File(java.net.URI)
1.696 + * @see java.net.URI
1.697 + * @see java.net.URI#toURL()
1.698 + * @since 1.4
1.699 + */
1.700 + public URI toURI() {
1.701 + try {
1.702 + File f = getAbsoluteFile();
1.703 + String sp = slashify(f.getPath(), f.isDirectory());
1.704 + if (sp.startsWith("//"))
1.705 + sp = "//" + sp;
1.706 + return new URI("file", null, sp, null);
1.707 + } catch (URISyntaxException x) {
1.708 + throw new Error(x); // Can't happen
1.709 + }
1.710 + }
1.711 +
1.712 +
1.713 + /* -- Attribute accessors -- */
1.714 +
1.715 + /**
1.716 + * Tests whether the application can read the file denoted by this
1.717 + * abstract pathname.
1.718 + *
1.719 + * @return <code>true</code> if and only if the file specified by this
1.720 + * abstract pathname exists <em>and</em> can be read by the
1.721 + * application; <code>false</code> otherwise
1.722 + *
1.723 + * @throws SecurityException
1.724 + * If a security manager exists and its <code>{@link
1.725 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1.726 + * method denies read access to the file
1.727 + */
1.728 + public boolean canRead() {
1.729 + SecurityManager security = System.getSecurityManager();
1.730 + if (security != null) {
1.731 + security.checkRead(path);
1.732 + }
1.733 + return fs.checkAccess(this, FileSystem.ACCESS_READ);
1.734 + }
1.735 +
1.736 + /**
1.737 + * Tests whether the application can modify the file denoted by this
1.738 + * abstract pathname.
1.739 + *
1.740 + * @return <code>true</code> if and only if the file system actually
1.741 + * contains a file denoted by this abstract pathname <em>and</em>
1.742 + * the application is allowed to write to the file;
1.743 + * <code>false</code> otherwise.
1.744 + *
1.745 + * @throws SecurityException
1.746 + * If a security manager exists and its <code>{@link
1.747 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.748 + * method denies write access to the file
1.749 + */
1.750 + public boolean canWrite() {
1.751 + SecurityManager security = System.getSecurityManager();
1.752 + if (security != null) {
1.753 + security.checkWrite(path);
1.754 + }
1.755 + return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
1.756 + }
1.757 +
1.758 + /**
1.759 + * Tests whether the file or directory denoted by this abstract pathname
1.760 + * exists.
1.761 + *
1.762 + * @return <code>true</code> if and only if the file or directory denoted
1.763 + * by this abstract pathname exists; <code>false</code> otherwise
1.764 + *
1.765 + * @throws SecurityException
1.766 + * If a security manager exists and its <code>{@link
1.767 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1.768 + * method denies read access to the file or directory
1.769 + */
1.770 + public boolean exists() {
1.771 + SecurityManager security = System.getSecurityManager();
1.772 + if (security != null) {
1.773 + security.checkRead(path);
1.774 + }
1.775 + return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
1.776 + }
1.777 +
1.778 + /**
1.779 + * Tests whether the file denoted by this abstract pathname is a
1.780 + * directory.
1.781 + *
1.782 + * <p> Where it is required to distinguish an I/O exception from the case
1.783 + * that the file is not a directory, or where several attributes of the
1.784 + * same file are required at the same time, then the {@link
1.785 + * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
1.786 + * Files.readAttributes} method may be used.
1.787 + *
1.788 + * @return <code>true</code> if and only if the file denoted by this
1.789 + * abstract pathname exists <em>and</em> is a directory;
1.790 + * <code>false</code> otherwise
1.791 + *
1.792 + * @throws SecurityException
1.793 + * If a security manager exists and its <code>{@link
1.794 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1.795 + * method denies read access to the file
1.796 + */
1.797 + public boolean isDirectory() {
1.798 + SecurityManager security = System.getSecurityManager();
1.799 + if (security != null) {
1.800 + security.checkRead(path);
1.801 + }
1.802 + return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
1.803 + != 0);
1.804 + }
1.805 +
1.806 + /**
1.807 + * Tests whether the file denoted by this abstract pathname is a normal
1.808 + * file. A file is <em>normal</em> if it is not a directory and, in
1.809 + * addition, satisfies other system-dependent criteria. Any non-directory
1.810 + * file created by a Java application is guaranteed to be a normal file.
1.811 + *
1.812 + * <p> Where it is required to distinguish an I/O exception from the case
1.813 + * that the file is not a normal file, or where several attributes of the
1.814 + * same file are required at the same time, then the {@link
1.815 + * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
1.816 + * Files.readAttributes} method may be used.
1.817 + *
1.818 + * @return <code>true</code> if and only if the file denoted by this
1.819 + * abstract pathname exists <em>and</em> is a normal file;
1.820 + * <code>false</code> otherwise
1.821 + *
1.822 + * @throws SecurityException
1.823 + * If a security manager exists and its <code>{@link
1.824 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1.825 + * method denies read access to the file
1.826 + */
1.827 + public boolean isFile() {
1.828 + SecurityManager security = System.getSecurityManager();
1.829 + if (security != null) {
1.830 + security.checkRead(path);
1.831 + }
1.832 + return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
1.833 + }
1.834 +
1.835 + /**
1.836 + * Tests whether the file named by this abstract pathname is a hidden
1.837 + * file. The exact definition of <em>hidden</em> is system-dependent. On
1.838 + * UNIX systems, a file is considered to be hidden if its name begins with
1.839 + * a period character (<code>'.'</code>). On Microsoft Windows systems, a file is
1.840 + * considered to be hidden if it has been marked as such in the filesystem.
1.841 + *
1.842 + * @return <code>true</code> if and only if the file denoted by this
1.843 + * abstract pathname is hidden according to the conventions of the
1.844 + * underlying platform
1.845 + *
1.846 + * @throws SecurityException
1.847 + * If a security manager exists and its <code>{@link
1.848 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1.849 + * method denies read access to the file
1.850 + *
1.851 + * @since 1.2
1.852 + */
1.853 + public boolean isHidden() {
1.854 + SecurityManager security = System.getSecurityManager();
1.855 + if (security != null) {
1.856 + security.checkRead(path);
1.857 + }
1.858 + return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
1.859 + }
1.860 +
1.861 + /**
1.862 + * Returns the time that the file denoted by this abstract pathname was
1.863 + * last modified.
1.864 + *
1.865 + * <p> Where it is required to distinguish an I/O exception from the case
1.866 + * where {@code 0L} is returned, or where several attributes of the
1.867 + * same file are required at the same time, or where the time of last
1.868 + * access or the creation time are required, then the {@link
1.869 + * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
1.870 + * Files.readAttributes} method may be used.
1.871 + *
1.872 + * @return A <code>long</code> value representing the time the file was
1.873 + * last modified, measured in milliseconds since the epoch
1.874 + * (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
1.875 + * file does not exist or if an I/O error occurs
1.876 + *
1.877 + * @throws SecurityException
1.878 + * If a security manager exists and its <code>{@link
1.879 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1.880 + * method denies read access to the file
1.881 + */
1.882 + public long lastModified() {
1.883 + SecurityManager security = System.getSecurityManager();
1.884 + if (security != null) {
1.885 + security.checkRead(path);
1.886 + }
1.887 + return fs.getLastModifiedTime(this);
1.888 + }
1.889 +
1.890 + /**
1.891 + * Returns the length of the file denoted by this abstract pathname.
1.892 + * The return value is unspecified if this pathname denotes a directory.
1.893 + *
1.894 + * <p> Where it is required to distinguish an I/O exception from the case
1.895 + * that {@code 0L} is returned, or where several attributes of the same file
1.896 + * are required at the same time, then the {@link
1.897 + * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
1.898 + * Files.readAttributes} method may be used.
1.899 + *
1.900 + * @return The length, in bytes, of the file denoted by this abstract
1.901 + * pathname, or <code>0L</code> if the file does not exist. Some
1.902 + * operating systems may return <code>0L</code> for pathnames
1.903 + * denoting system-dependent entities such as devices or pipes.
1.904 + *
1.905 + * @throws SecurityException
1.906 + * If a security manager exists and its <code>{@link
1.907 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1.908 + * method denies read access to the file
1.909 + */
1.910 + public long length() {
1.911 + SecurityManager security = System.getSecurityManager();
1.912 + if (security != null) {
1.913 + security.checkRead(path);
1.914 + }
1.915 + return fs.getLength(this);
1.916 + }
1.917 +
1.918 +
1.919 + /* -- File operations -- */
1.920 +
1.921 + /**
1.922 + * Atomically creates a new, empty file named by this abstract pathname if
1.923 + * and only if a file with this name does not yet exist. The check for the
1.924 + * existence of the file and the creation of the file if it does not exist
1.925 + * are a single operation that is atomic with respect to all other
1.926 + * filesystem activities that might affect the file.
1.927 + * <P>
1.928 + * Note: this method should <i>not</i> be used for file-locking, as
1.929 + * the resulting protocol cannot be made to work reliably. The
1.930 + * {@link java.nio.channels.FileLock FileLock}
1.931 + * facility should be used instead.
1.932 + *
1.933 + * @return <code>true</code> if the named file does not exist and was
1.934 + * successfully created; <code>false</code> if the named file
1.935 + * already exists
1.936 + *
1.937 + * @throws IOException
1.938 + * If an I/O error occurred
1.939 + *
1.940 + * @throws SecurityException
1.941 + * If a security manager exists and its <code>{@link
1.942 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.943 + * method denies write access to the file
1.944 + *
1.945 + * @since 1.2
1.946 + */
1.947 + public boolean createNewFile() throws IOException {
1.948 + SecurityManager security = System.getSecurityManager();
1.949 + if (security != null) security.checkWrite(path);
1.950 + return fs.createFileExclusively(path);
1.951 + }
1.952 +
1.953 + /**
1.954 + * Deletes the file or directory denoted by this abstract pathname. If
1.955 + * this pathname denotes a directory, then the directory must be empty in
1.956 + * order to be deleted.
1.957 + *
1.958 + * <p> Note that the {@link java.nio.file.Files} class defines the {@link
1.959 + * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException}
1.960 + * when a file cannot be deleted. This is useful for error reporting and to
1.961 + * diagnose why a file cannot be deleted.
1.962 + *
1.963 + * @return <code>true</code> if and only if the file or directory is
1.964 + * successfully deleted; <code>false</code> otherwise
1.965 + *
1.966 + * @throws SecurityException
1.967 + * If a security manager exists and its <code>{@link
1.968 + * java.lang.SecurityManager#checkDelete}</code> method denies
1.969 + * delete access to the file
1.970 + */
1.971 + public boolean delete() {
1.972 + SecurityManager security = System.getSecurityManager();
1.973 + if (security != null) {
1.974 + security.checkDelete(path);
1.975 + }
1.976 + return fs.delete(this);
1.977 + }
1.978 +
1.979 + /**
1.980 + * Requests that the file or directory denoted by this abstract
1.981 + * pathname be deleted when the virtual machine terminates.
1.982 + * Files (or directories) are deleted in the reverse order that
1.983 + * they are registered. Invoking this method to delete a file or
1.984 + * directory that is already registered for deletion has no effect.
1.985 + * Deletion will be attempted only for normal termination of the
1.986 + * virtual machine, as defined by the Java Language Specification.
1.987 + *
1.988 + * <p> Once deletion has been requested, it is not possible to cancel the
1.989 + * request. This method should therefore be used with care.
1.990 + *
1.991 + * <P>
1.992 + * Note: this method should <i>not</i> be used for file-locking, as
1.993 + * the resulting protocol cannot be made to work reliably. The
1.994 + * {@link java.nio.channels.FileLock FileLock}
1.995 + * facility should be used instead.
1.996 + *
1.997 + * @throws SecurityException
1.998 + * If a security manager exists and its <code>{@link
1.999 + * java.lang.SecurityManager#checkDelete}</code> method denies
1.1000 + * delete access to the file
1.1001 + *
1.1002 + * @see #delete
1.1003 + *
1.1004 + * @since 1.2
1.1005 + */
1.1006 + public void deleteOnExit() {
1.1007 + SecurityManager security = System.getSecurityManager();
1.1008 + if (security != null) {
1.1009 + security.checkDelete(path);
1.1010 + }
1.1011 + DeleteOnExitHook.add(path);
1.1012 + }
1.1013 +
1.1014 + /**
1.1015 + * Returns an array of strings naming the files and directories in the
1.1016 + * directory denoted by this abstract pathname.
1.1017 + *
1.1018 + * <p> If this abstract pathname does not denote a directory, then this
1.1019 + * method returns {@code null}. Otherwise an array of strings is
1.1020 + * returned, one for each file or directory in the directory. Names
1.1021 + * denoting the directory itself and the directory's parent directory are
1.1022 + * not included in the result. Each string is a file name rather than a
1.1023 + * complete path.
1.1024 + *
1.1025 + * <p> There is no guarantee that the name strings in the resulting array
1.1026 + * will appear in any specific order; they are not, in particular,
1.1027 + * guaranteed to appear in alphabetical order.
1.1028 + *
1.1029 + * <p> Note that the {@link java.nio.file.Files} class defines the {@link
1.1030 + * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to
1.1031 + * open a directory and iterate over the names of the files in the directory.
1.1032 + * This may use less resources when working with very large directories, and
1.1033 + * may be more responsive when working with remote directories.
1.1034 + *
1.1035 + * @return An array of strings naming the files and directories in the
1.1036 + * directory denoted by this abstract pathname. The array will be
1.1037 + * empty if the directory is empty. Returns {@code null} if
1.1038 + * this abstract pathname does not denote a directory, or if an
1.1039 + * I/O error occurs.
1.1040 + *
1.1041 + * @throws SecurityException
1.1042 + * If a security manager exists and its {@link
1.1043 + * SecurityManager#checkRead(String)} method denies read access to
1.1044 + * the directory
1.1045 + */
1.1046 + public String[] list() {
1.1047 + SecurityManager security = System.getSecurityManager();
1.1048 + if (security != null) {
1.1049 + security.checkRead(path);
1.1050 + }
1.1051 + return fs.list(this);
1.1052 + }
1.1053 +
1.1054 + /**
1.1055 + * Returns an array of strings naming the files and directories in the
1.1056 + * directory denoted by this abstract pathname that satisfy the specified
1.1057 + * filter. The behavior of this method is the same as that of the
1.1058 + * {@link #list()} method, except that the strings in the returned array
1.1059 + * must satisfy the filter. If the given {@code filter} is {@code null}
1.1060 + * then all names are accepted. Otherwise, a name satisfies the filter if
1.1061 + * and only if the value {@code true} results when the {@link
1.1062 + * FilenameFilter#accept FilenameFilter.accept(File, String)} method
1.1063 + * of the filter is invoked on this abstract pathname and the name of a
1.1064 + * file or directory in the directory that it denotes.
1.1065 + *
1.1066 + * @param filter
1.1067 + * A filename filter
1.1068 + *
1.1069 + * @return An array of strings naming the files and directories in the
1.1070 + * directory denoted by this abstract pathname that were accepted
1.1071 + * by the given {@code filter}. The array will be empty if the
1.1072 + * directory is empty or if no names were accepted by the filter.
1.1073 + * Returns {@code null} if this abstract pathname does not denote
1.1074 + * a directory, or if an I/O error occurs.
1.1075 + *
1.1076 + * @throws SecurityException
1.1077 + * If a security manager exists and its {@link
1.1078 + * SecurityManager#checkRead(String)} method denies read access to
1.1079 + * the directory
1.1080 + *
1.1081 + * @see java.nio.file.Files#newDirectoryStream(Path,String)
1.1082 + */
1.1083 + public String[] list(FilenameFilter filter) {
1.1084 + String names[] = list();
1.1085 + if ((names == null) || (filter == null)) {
1.1086 + return names;
1.1087 + }
1.1088 + List<String> v = new ArrayList<>();
1.1089 + for (int i = 0 ; i < names.length ; i++) {
1.1090 + if (filter.accept(this, names[i])) {
1.1091 + v.add(names[i]);
1.1092 + }
1.1093 + }
1.1094 + return v.toArray(new String[v.size()]);
1.1095 + }
1.1096 +
1.1097 + /**
1.1098 + * Returns an array of abstract pathnames denoting the files in the
1.1099 + * directory denoted by this abstract pathname.
1.1100 + *
1.1101 + * <p> If this abstract pathname does not denote a directory, then this
1.1102 + * method returns {@code null}. Otherwise an array of {@code File} objects
1.1103 + * is returned, one for each file or directory in the directory. Pathnames
1.1104 + * denoting the directory itself and the directory's parent directory are
1.1105 + * not included in the result. Each resulting abstract pathname is
1.1106 + * constructed from this abstract pathname using the {@link #File(File,
1.1107 + * String) File(File, String)} constructor. Therefore if this
1.1108 + * pathname is absolute then each resulting pathname is absolute; if this
1.1109 + * pathname is relative then each resulting pathname will be relative to
1.1110 + * the same directory.
1.1111 + *
1.1112 + * <p> There is no guarantee that the name strings in the resulting array
1.1113 + * will appear in any specific order; they are not, in particular,
1.1114 + * guaranteed to appear in alphabetical order.
1.1115 + *
1.1116 + * <p> Note that the {@link java.nio.file.Files} class defines the {@link
1.1117 + * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method
1.1118 + * to open a directory and iterate over the names of the files in the
1.1119 + * directory. This may use less resources when working with very large
1.1120 + * directories.
1.1121 + *
1.1122 + * @return An array of abstract pathnames denoting the files and
1.1123 + * directories in the directory denoted by this abstract pathname.
1.1124 + * The array will be empty if the directory is empty. Returns
1.1125 + * {@code null} if this abstract pathname does not denote a
1.1126 + * directory, or if an I/O error occurs.
1.1127 + *
1.1128 + * @throws SecurityException
1.1129 + * If a security manager exists and its {@link
1.1130 + * SecurityManager#checkRead(String)} method denies read access to
1.1131 + * the directory
1.1132 + *
1.1133 + * @since 1.2
1.1134 + */
1.1135 + public File[] listFiles() {
1.1136 + String[] ss = list();
1.1137 + if (ss == null) return null;
1.1138 + int n = ss.length;
1.1139 + File[] fs = new File[n];
1.1140 + for (int i = 0; i < n; i++) {
1.1141 + fs[i] = new File(ss[i], this);
1.1142 + }
1.1143 + return fs;
1.1144 + }
1.1145 +
1.1146 + /**
1.1147 + * Returns an array of abstract pathnames denoting the files and
1.1148 + * directories in the directory denoted by this abstract pathname that
1.1149 + * satisfy the specified filter. The behavior of this method is the same
1.1150 + * as that of the {@link #listFiles()} method, except that the pathnames in
1.1151 + * the returned array must satisfy the filter. If the given {@code filter}
1.1152 + * is {@code null} then all pathnames are accepted. Otherwise, a pathname
1.1153 + * satisfies the filter if and only if the value {@code true} results when
1.1154 + * the {@link FilenameFilter#accept
1.1155 + * FilenameFilter.accept(File, String)} method of the filter is
1.1156 + * invoked on this abstract pathname and the name of a file or directory in
1.1157 + * the directory that it denotes.
1.1158 + *
1.1159 + * @param filter
1.1160 + * A filename filter
1.1161 + *
1.1162 + * @return An array of abstract pathnames denoting the files and
1.1163 + * directories in the directory denoted by this abstract pathname.
1.1164 + * The array will be empty if the directory is empty. Returns
1.1165 + * {@code null} if this abstract pathname does not denote a
1.1166 + * directory, or if an I/O error occurs.
1.1167 + *
1.1168 + * @throws SecurityException
1.1169 + * If a security manager exists and its {@link
1.1170 + * SecurityManager#checkRead(String)} method denies read access to
1.1171 + * the directory
1.1172 + *
1.1173 + * @since 1.2
1.1174 + * @see java.nio.file.Files#newDirectoryStream(Path,String)
1.1175 + */
1.1176 + public File[] listFiles(FilenameFilter filter) {
1.1177 + String ss[] = list();
1.1178 + if (ss == null) return null;
1.1179 + ArrayList<File> files = new ArrayList<>();
1.1180 + for (String s : ss)
1.1181 + if ((filter == null) || filter.accept(this, s))
1.1182 + files.add(new File(s, this));
1.1183 + return files.toArray(new File[files.size()]);
1.1184 + }
1.1185 +
1.1186 + /**
1.1187 + * Returns an array of abstract pathnames denoting the files and
1.1188 + * directories in the directory denoted by this abstract pathname that
1.1189 + * satisfy the specified filter. The behavior of this method is the same
1.1190 + * as that of the {@link #listFiles()} method, except that the pathnames in
1.1191 + * the returned array must satisfy the filter. If the given {@code filter}
1.1192 + * is {@code null} then all pathnames are accepted. Otherwise, a pathname
1.1193 + * satisfies the filter if and only if the value {@code true} results when
1.1194 + * the {@link FileFilter#accept FileFilter.accept(File)} method of the
1.1195 + * filter is invoked on the pathname.
1.1196 + *
1.1197 + * @param filter
1.1198 + * A file filter
1.1199 + *
1.1200 + * @return An array of abstract pathnames denoting the files and
1.1201 + * directories in the directory denoted by this abstract pathname.
1.1202 + * The array will be empty if the directory is empty. Returns
1.1203 + * {@code null} if this abstract pathname does not denote a
1.1204 + * directory, or if an I/O error occurs.
1.1205 + *
1.1206 + * @throws SecurityException
1.1207 + * If a security manager exists and its {@link
1.1208 + * SecurityManager#checkRead(String)} method denies read access to
1.1209 + * the directory
1.1210 + *
1.1211 + * @since 1.2
1.1212 + * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter)
1.1213 + */
1.1214 + public File[] listFiles(FileFilter filter) {
1.1215 + String ss[] = list();
1.1216 + if (ss == null) return null;
1.1217 + ArrayList<File> files = new ArrayList<>();
1.1218 + for (String s : ss) {
1.1219 + File f = new File(s, this);
1.1220 + if ((filter == null) || filter.accept(f))
1.1221 + files.add(f);
1.1222 + }
1.1223 + return files.toArray(new File[files.size()]);
1.1224 + }
1.1225 +
1.1226 + /**
1.1227 + * Creates the directory named by this abstract pathname.
1.1228 + *
1.1229 + * @return <code>true</code> if and only if the directory was
1.1230 + * created; <code>false</code> otherwise
1.1231 + *
1.1232 + * @throws SecurityException
1.1233 + * If a security manager exists and its <code>{@link
1.1234 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1235 + * method does not permit the named directory to be created
1.1236 + */
1.1237 + public boolean mkdir() {
1.1238 + SecurityManager security = System.getSecurityManager();
1.1239 + if (security != null) {
1.1240 + security.checkWrite(path);
1.1241 + }
1.1242 + return fs.createDirectory(this);
1.1243 + }
1.1244 +
1.1245 + /**
1.1246 + * Creates the directory named by this abstract pathname, including any
1.1247 + * necessary but nonexistent parent directories. Note that if this
1.1248 + * operation fails it may have succeeded in creating some of the necessary
1.1249 + * parent directories.
1.1250 + *
1.1251 + * @return <code>true</code> if and only if the directory was created,
1.1252 + * along with all necessary parent directories; <code>false</code>
1.1253 + * otherwise
1.1254 + *
1.1255 + * @throws SecurityException
1.1256 + * If a security manager exists and its <code>{@link
1.1257 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1.1258 + * method does not permit verification of the existence of the
1.1259 + * named directory and all necessary parent directories; or if
1.1260 + * the <code>{@link
1.1261 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1262 + * method does not permit the named directory and all necessary
1.1263 + * parent directories to be created
1.1264 + */
1.1265 + public boolean mkdirs() {
1.1266 + if (exists()) {
1.1267 + return false;
1.1268 + }
1.1269 + if (mkdir()) {
1.1270 + return true;
1.1271 + }
1.1272 + File canonFile = null;
1.1273 + try {
1.1274 + canonFile = getCanonicalFile();
1.1275 + } catch (IOException e) {
1.1276 + return false;
1.1277 + }
1.1278 +
1.1279 + File parent = canonFile.getParentFile();
1.1280 + return (parent != null && (parent.mkdirs() || parent.exists()) &&
1.1281 + canonFile.mkdir());
1.1282 + }
1.1283 +
1.1284 + /**
1.1285 + * Renames the file denoted by this abstract pathname.
1.1286 + *
1.1287 + * <p> Many aspects of the behavior of this method are inherently
1.1288 + * platform-dependent: The rename operation might not be able to move a
1.1289 + * file from one filesystem to another, it might not be atomic, and it
1.1290 + * might not succeed if a file with the destination abstract pathname
1.1291 + * already exists. The return value should always be checked to make sure
1.1292 + * that the rename operation was successful.
1.1293 + *
1.1294 + * <p> Note that the {@link java.nio.file.Files} class defines the {@link
1.1295 + * java.nio.file.Files#move move} method to move or rename a file in a
1.1296 + * platform independent manner.
1.1297 + *
1.1298 + * @param dest The new abstract pathname for the named file
1.1299 + *
1.1300 + * @return <code>true</code> if and only if the renaming succeeded;
1.1301 + * <code>false</code> otherwise
1.1302 + *
1.1303 + * @throws SecurityException
1.1304 + * If a security manager exists and its <code>{@link
1.1305 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1306 + * method denies write access to either the old or new pathnames
1.1307 + *
1.1308 + * @throws NullPointerException
1.1309 + * If parameter <code>dest</code> is <code>null</code>
1.1310 + */
1.1311 + public boolean renameTo(File dest) {
1.1312 + SecurityManager security = System.getSecurityManager();
1.1313 + if (security != null) {
1.1314 + security.checkWrite(path);
1.1315 + security.checkWrite(dest.path);
1.1316 + }
1.1317 + return fs.rename(this, dest);
1.1318 + }
1.1319 +
1.1320 + /**
1.1321 + * Sets the last-modified time of the file or directory named by this
1.1322 + * abstract pathname.
1.1323 + *
1.1324 + * <p> All platforms support file-modification times to the nearest second,
1.1325 + * but some provide more precision. The argument will be truncated to fit
1.1326 + * the supported precision. If the operation succeeds and no intervening
1.1327 + * operations on the file take place, then the next invocation of the
1.1328 + * <code>{@link #lastModified}</code> method will return the (possibly
1.1329 + * truncated) <code>time</code> argument that was passed to this method.
1.1330 + *
1.1331 + * @param time The new last-modified time, measured in milliseconds since
1.1332 + * the epoch (00:00:00 GMT, January 1, 1970)
1.1333 + *
1.1334 + * @return <code>true</code> if and only if the operation succeeded;
1.1335 + * <code>false</code> otherwise
1.1336 + *
1.1337 + * @throws IllegalArgumentException If the argument is negative
1.1338 + *
1.1339 + * @throws SecurityException
1.1340 + * If a security manager exists and its <code>{@link
1.1341 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1342 + * method denies write access to the named file
1.1343 + *
1.1344 + * @since 1.2
1.1345 + */
1.1346 + public boolean setLastModified(long time) {
1.1347 + if (time < 0) throw new IllegalArgumentException("Negative time");
1.1348 + SecurityManager security = System.getSecurityManager();
1.1349 + if (security != null) {
1.1350 + security.checkWrite(path);
1.1351 + }
1.1352 + return fs.setLastModifiedTime(this, time);
1.1353 + }
1.1354 +
1.1355 + /**
1.1356 + * Marks the file or directory named by this abstract pathname so that
1.1357 + * only read operations are allowed. After invoking this method the file
1.1358 + * or directory is guaranteed not to change until it is either deleted or
1.1359 + * marked to allow write access. Whether or not a read-only file or
1.1360 + * directory may be deleted depends upon the underlying system.
1.1361 + *
1.1362 + * @return <code>true</code> if and only if the operation succeeded;
1.1363 + * <code>false</code> otherwise
1.1364 + *
1.1365 + * @throws SecurityException
1.1366 + * If a security manager exists and its <code>{@link
1.1367 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1368 + * method denies write access to the named file
1.1369 + *
1.1370 + * @since 1.2
1.1371 + */
1.1372 + public boolean setReadOnly() {
1.1373 + SecurityManager security = System.getSecurityManager();
1.1374 + if (security != null) {
1.1375 + security.checkWrite(path);
1.1376 + }
1.1377 + return fs.setReadOnly(this);
1.1378 + }
1.1379 +
1.1380 + /**
1.1381 + * Sets the owner's or everybody's write permission for this abstract
1.1382 + * pathname.
1.1383 + *
1.1384 + * <p> The {@link java.nio.file.Files} class defines methods that operate on
1.1385 + * file attributes including file permissions. This may be used when finer
1.1386 + * manipulation of file permissions is required.
1.1387 + *
1.1388 + * @param writable
1.1389 + * If <code>true</code>, sets the access permission to allow write
1.1390 + * operations; if <code>false</code> to disallow write operations
1.1391 + *
1.1392 + * @param ownerOnly
1.1393 + * If <code>true</code>, the write permission applies only to the
1.1394 + * owner's write permission; otherwise, it applies to everybody. If
1.1395 + * the underlying file system can not distinguish the owner's write
1.1396 + * permission from that of others, then the permission will apply to
1.1397 + * everybody, regardless of this value.
1.1398 + *
1.1399 + * @return <code>true</code> if and only if the operation succeeded. The
1.1400 + * operation will fail if the user does not have permission to change
1.1401 + * the access permissions of this abstract pathname.
1.1402 + *
1.1403 + * @throws SecurityException
1.1404 + * If a security manager exists and its <code>{@link
1.1405 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1406 + * method denies write access to the named file
1.1407 + *
1.1408 + * @since 1.6
1.1409 + */
1.1410 + public boolean setWritable(boolean writable, boolean ownerOnly) {
1.1411 + SecurityManager security = System.getSecurityManager();
1.1412 + if (security != null) {
1.1413 + security.checkWrite(path);
1.1414 + }
1.1415 + return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
1.1416 + }
1.1417 +
1.1418 + /**
1.1419 + * A convenience method to set the owner's write permission for this abstract
1.1420 + * pathname.
1.1421 + *
1.1422 + * <p> An invocation of this method of the form <tt>file.setWritable(arg)</tt>
1.1423 + * behaves in exactly the same way as the invocation
1.1424 + *
1.1425 + * <pre>
1.1426 + * file.setWritable(arg, true) </pre>
1.1427 + *
1.1428 + * @param writable
1.1429 + * If <code>true</code>, sets the access permission to allow write
1.1430 + * operations; if <code>false</code> to disallow write operations
1.1431 + *
1.1432 + * @return <code>true</code> if and only if the operation succeeded. The
1.1433 + * operation will fail if the user does not have permission to
1.1434 + * change the access permissions of this abstract pathname.
1.1435 + *
1.1436 + * @throws SecurityException
1.1437 + * If a security manager exists and its <code>{@link
1.1438 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1439 + * method denies write access to the file
1.1440 + *
1.1441 + * @since 1.6
1.1442 + */
1.1443 + public boolean setWritable(boolean writable) {
1.1444 + return setWritable(writable, true);
1.1445 + }
1.1446 +
1.1447 + /**
1.1448 + * Sets the owner's or everybody's read permission for this abstract
1.1449 + * pathname.
1.1450 + *
1.1451 + * <p> The {@link java.nio.file.Files} class defines methods that operate on
1.1452 + * file attributes including file permissions. This may be used when finer
1.1453 + * manipulation of file permissions is required.
1.1454 + *
1.1455 + * @param readable
1.1456 + * If <code>true</code>, sets the access permission to allow read
1.1457 + * operations; if <code>false</code> to disallow read operations
1.1458 + *
1.1459 + * @param ownerOnly
1.1460 + * If <code>true</code>, the read permission applies only to the
1.1461 + * owner's read permission; otherwise, it applies to everybody. If
1.1462 + * the underlying file system can not distinguish the owner's read
1.1463 + * permission from that of others, then the permission will apply to
1.1464 + * everybody, regardless of this value.
1.1465 + *
1.1466 + * @return <code>true</code> if and only if the operation succeeded. The
1.1467 + * operation will fail if the user does not have permission to
1.1468 + * change the access permissions of this abstract pathname. If
1.1469 + * <code>readable</code> is <code>false</code> and the underlying
1.1470 + * file system does not implement a read permission, then the
1.1471 + * operation will fail.
1.1472 + *
1.1473 + * @throws SecurityException
1.1474 + * If a security manager exists and its <code>{@link
1.1475 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1476 + * method denies write access to the file
1.1477 + *
1.1478 + * @since 1.6
1.1479 + */
1.1480 + public boolean setReadable(boolean readable, boolean ownerOnly) {
1.1481 + SecurityManager security = System.getSecurityManager();
1.1482 + if (security != null) {
1.1483 + security.checkWrite(path);
1.1484 + }
1.1485 + return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
1.1486 + }
1.1487 +
1.1488 + /**
1.1489 + * A convenience method to set the owner's read permission for this abstract
1.1490 + * pathname.
1.1491 + *
1.1492 + * <p>An invocation of this method of the form <tt>file.setReadable(arg)</tt>
1.1493 + * behaves in exactly the same way as the invocation
1.1494 + *
1.1495 + * <pre>
1.1496 + * file.setReadable(arg, true) </pre>
1.1497 + *
1.1498 + * @param readable
1.1499 + * If <code>true</code>, sets the access permission to allow read
1.1500 + * operations; if <code>false</code> to disallow read operations
1.1501 + *
1.1502 + * @return <code>true</code> if and only if the operation succeeded. The
1.1503 + * operation will fail if the user does not have permission to
1.1504 + * change the access permissions of this abstract pathname. If
1.1505 + * <code>readable</code> is <code>false</code> and the underlying
1.1506 + * file system does not implement a read permission, then the
1.1507 + * operation will fail.
1.1508 + *
1.1509 + * @throws SecurityException
1.1510 + * If a security manager exists and its <code>{@link
1.1511 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1512 + * method denies write access to the file
1.1513 + *
1.1514 + * @since 1.6
1.1515 + */
1.1516 + public boolean setReadable(boolean readable) {
1.1517 + return setReadable(readable, true);
1.1518 + }
1.1519 +
1.1520 + /**
1.1521 + * Sets the owner's or everybody's execute permission for this abstract
1.1522 + * pathname.
1.1523 + *
1.1524 + * <p> The {@link java.nio.file.Files} class defines methods that operate on
1.1525 + * file attributes including file permissions. This may be used when finer
1.1526 + * manipulation of file permissions is required.
1.1527 + *
1.1528 + * @param executable
1.1529 + * If <code>true</code>, sets the access permission to allow execute
1.1530 + * operations; if <code>false</code> to disallow execute operations
1.1531 + *
1.1532 + * @param ownerOnly
1.1533 + * If <code>true</code>, the execute permission applies only to the
1.1534 + * owner's execute permission; otherwise, it applies to everybody.
1.1535 + * If the underlying file system can not distinguish the owner's
1.1536 + * execute permission from that of others, then the permission will
1.1537 + * apply to everybody, regardless of this value.
1.1538 + *
1.1539 + * @return <code>true</code> if and only if the operation succeeded. The
1.1540 + * operation will fail if the user does not have permission to
1.1541 + * change the access permissions of this abstract pathname. If
1.1542 + * <code>executable</code> is <code>false</code> and the underlying
1.1543 + * file system does not implement an execute permission, then the
1.1544 + * operation will fail.
1.1545 + *
1.1546 + * @throws SecurityException
1.1547 + * If a security manager exists and its <code>{@link
1.1548 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1549 + * method denies write access to the file
1.1550 + *
1.1551 + * @since 1.6
1.1552 + */
1.1553 + public boolean setExecutable(boolean executable, boolean ownerOnly) {
1.1554 + SecurityManager security = System.getSecurityManager();
1.1555 + if (security != null) {
1.1556 + security.checkWrite(path);
1.1557 + }
1.1558 + return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
1.1559 + }
1.1560 +
1.1561 + /**
1.1562 + * A convenience method to set the owner's execute permission for this abstract
1.1563 + * pathname.
1.1564 + *
1.1565 + * <p>An invocation of this method of the form <tt>file.setExcutable(arg)</tt>
1.1566 + * behaves in exactly the same way as the invocation
1.1567 + *
1.1568 + * <pre>
1.1569 + * file.setExecutable(arg, true) </pre>
1.1570 + *
1.1571 + * @param executable
1.1572 + * If <code>true</code>, sets the access permission to allow execute
1.1573 + * operations; if <code>false</code> to disallow execute operations
1.1574 + *
1.1575 + * @return <code>true</code> if and only if the operation succeeded. The
1.1576 + * operation will fail if the user does not have permission to
1.1577 + * change the access permissions of this abstract pathname. If
1.1578 + * <code>executable</code> is <code>false</code> and the underlying
1.1579 + * file system does not implement an excute permission, then the
1.1580 + * operation will fail.
1.1581 + *
1.1582 + * @throws SecurityException
1.1583 + * If a security manager exists and its <code>{@link
1.1584 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1585 + * method denies write access to the file
1.1586 + *
1.1587 + * @since 1.6
1.1588 + */
1.1589 + public boolean setExecutable(boolean executable) {
1.1590 + return setExecutable(executable, true);
1.1591 + }
1.1592 +
1.1593 + /**
1.1594 + * Tests whether the application can execute the file denoted by this
1.1595 + * abstract pathname.
1.1596 + *
1.1597 + * @return <code>true</code> if and only if the abstract pathname exists
1.1598 + * <em>and</em> the application is allowed to execute the file
1.1599 + *
1.1600 + * @throws SecurityException
1.1601 + * If a security manager exists and its <code>{@link
1.1602 + * java.lang.SecurityManager#checkExec(java.lang.String)}</code>
1.1603 + * method denies execute access to the file
1.1604 + *
1.1605 + * @since 1.6
1.1606 + */
1.1607 + public boolean canExecute() {
1.1608 + SecurityManager security = System.getSecurityManager();
1.1609 + if (security != null) {
1.1610 + security.checkExec(path);
1.1611 + }
1.1612 + return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
1.1613 + }
1.1614 +
1.1615 +
1.1616 + /* -- Filesystem interface -- */
1.1617 +
1.1618 + /**
1.1619 + * List the available filesystem roots.
1.1620 + *
1.1621 + * <p> A particular Java platform may support zero or more
1.1622 + * hierarchically-organized file systems. Each file system has a
1.1623 + * {@code root} directory from which all other files in that file system
1.1624 + * can be reached. Windows platforms, for example, have a root directory
1.1625 + * for each active drive; UNIX platforms have a single root directory,
1.1626 + * namely {@code "/"}. The set of available filesystem roots is affected
1.1627 + * by various system-level operations such as the insertion or ejection of
1.1628 + * removable media and the disconnecting or unmounting of physical or
1.1629 + * virtual disk drives.
1.1630 + *
1.1631 + * <p> This method returns an array of {@code File} objects that denote the
1.1632 + * root directories of the available filesystem roots. It is guaranteed
1.1633 + * that the canonical pathname of any file physically present on the local
1.1634 + * machine will begin with one of the roots returned by this method.
1.1635 + *
1.1636 + * <p> The canonical pathname of a file that resides on some other machine
1.1637 + * and is accessed via a remote-filesystem protocol such as SMB or NFS may
1.1638 + * or may not begin with one of the roots returned by this method. If the
1.1639 + * pathname of a remote file is syntactically indistinguishable from the
1.1640 + * pathname of a local file then it will begin with one of the roots
1.1641 + * returned by this method. Thus, for example, {@code File} objects
1.1642 + * denoting the root directories of the mapped network drives of a Windows
1.1643 + * platform will be returned by this method, while {@code File} objects
1.1644 + * containing UNC pathnames will not be returned by this method.
1.1645 + *
1.1646 + * <p> Unlike most methods in this class, this method does not throw
1.1647 + * security exceptions. If a security manager exists and its {@link
1.1648 + * SecurityManager#checkRead(String)} method denies read access to a
1.1649 + * particular root directory, then that directory will not appear in the
1.1650 + * result.
1.1651 + *
1.1652 + * @return An array of {@code File} objects denoting the available
1.1653 + * filesystem roots, or {@code null} if the set of roots could not
1.1654 + * be determined. The array will be empty if there are no
1.1655 + * filesystem roots.
1.1656 + *
1.1657 + * @since 1.2
1.1658 + * @see java.nio.file.FileStore
1.1659 + */
1.1660 + public static File[] listRoots() {
1.1661 + return fs.listRoots();
1.1662 + }
1.1663 +
1.1664 +
1.1665 + /* -- Disk usage -- */
1.1666 +
1.1667 + /**
1.1668 + * Returns the size of the partition <a href="#partName">named</a> by this
1.1669 + * abstract pathname.
1.1670 + *
1.1671 + * @return The size, in bytes, of the partition or <tt>0L</tt> if this
1.1672 + * abstract pathname does not name a partition
1.1673 + *
1.1674 + * @throws SecurityException
1.1675 + * If a security manager has been installed and it denies
1.1676 + * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
1.1677 + * or its {@link SecurityManager#checkRead(String)} method denies
1.1678 + * read access to the file named by this abstract pathname
1.1679 + *
1.1680 + * @since 1.6
1.1681 + */
1.1682 + public long getTotalSpace() {
1.1683 + SecurityManager sm = System.getSecurityManager();
1.1684 + if (sm != null) {
1.1685 + sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
1.1686 + sm.checkRead(path);
1.1687 + }
1.1688 + return fs.getSpace(this, FileSystem.SPACE_TOTAL);
1.1689 + }
1.1690 +
1.1691 + /**
1.1692 + * Returns the number of unallocated bytes in the partition <a
1.1693 + * href="#partName">named</a> by this abstract path name.
1.1694 + *
1.1695 + * <p> The returned number of unallocated bytes is a hint, but not
1.1696 + * a guarantee, that it is possible to use most or any of these
1.1697 + * bytes. The number of unallocated bytes is most likely to be
1.1698 + * accurate immediately after this call. It is likely to be made
1.1699 + * inaccurate by any external I/O operations including those made
1.1700 + * on the system outside of this virtual machine. This method
1.1701 + * makes no guarantee that write operations to this file system
1.1702 + * will succeed.
1.1703 + *
1.1704 + * @return The number of unallocated bytes on the partition <tt>0L</tt>
1.1705 + * if the abstract pathname does not name a partition. This
1.1706 + * value will be less than or equal to the total file system size
1.1707 + * returned by {@link #getTotalSpace}.
1.1708 + *
1.1709 + * @throws SecurityException
1.1710 + * If a security manager has been installed and it denies
1.1711 + * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
1.1712 + * or its {@link SecurityManager#checkRead(String)} method denies
1.1713 + * read access to the file named by this abstract pathname
1.1714 + *
1.1715 + * @since 1.6
1.1716 + */
1.1717 + public long getFreeSpace() {
1.1718 + SecurityManager sm = System.getSecurityManager();
1.1719 + if (sm != null) {
1.1720 + sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
1.1721 + sm.checkRead(path);
1.1722 + }
1.1723 + return fs.getSpace(this, FileSystem.SPACE_FREE);
1.1724 + }
1.1725 +
1.1726 + /**
1.1727 + * Returns the number of bytes available to this virtual machine on the
1.1728 + * partition <a href="#partName">named</a> by this abstract pathname. When
1.1729 + * possible, this method checks for write permissions and other operating
1.1730 + * system restrictions and will therefore usually provide a more accurate
1.1731 + * estimate of how much new data can actually be written than {@link
1.1732 + * #getFreeSpace}.
1.1733 + *
1.1734 + * <p> The returned number of available bytes is a hint, but not a
1.1735 + * guarantee, that it is possible to use most or any of these bytes. The
1.1736 + * number of unallocated bytes is most likely to be accurate immediately
1.1737 + * after this call. It is likely to be made inaccurate by any external
1.1738 + * I/O operations including those made on the system outside of this
1.1739 + * virtual machine. This method makes no guarantee that write operations
1.1740 + * to this file system will succeed.
1.1741 + *
1.1742 + * @return The number of available bytes on the partition or <tt>0L</tt>
1.1743 + * if the abstract pathname does not name a partition. On
1.1744 + * systems where this information is not available, this method
1.1745 + * will be equivalent to a call to {@link #getFreeSpace}.
1.1746 + *
1.1747 + * @throws SecurityException
1.1748 + * If a security manager has been installed and it denies
1.1749 + * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
1.1750 + * or its {@link SecurityManager#checkRead(String)} method denies
1.1751 + * read access to the file named by this abstract pathname
1.1752 + *
1.1753 + * @since 1.6
1.1754 + */
1.1755 + public long getUsableSpace() {
1.1756 + SecurityManager sm = System.getSecurityManager();
1.1757 + if (sm != null) {
1.1758 + sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
1.1759 + sm.checkRead(path);
1.1760 + }
1.1761 + return fs.getSpace(this, FileSystem.SPACE_USABLE);
1.1762 + }
1.1763 +
1.1764 + /* -- Temporary files -- */
1.1765 +
1.1766 + private static class TempDirectory {
1.1767 + private TempDirectory() { }
1.1768 +
1.1769 + // temporary directory location
1.1770 + private static final File tmpdir = new File(fs.normalize(AccessController
1.1771 + .doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
1.1772 + static File location() {
1.1773 + return tmpdir;
1.1774 + }
1.1775 +
1.1776 + // file name generation
1.1777 + private static final SecureRandom random = new SecureRandom();
1.1778 + static File generateFile(String prefix, String suffix, File dir) {
1.1779 + long n = random.nextLong();
1.1780 + if (n == Long.MIN_VALUE) {
1.1781 + n = 0; // corner case
1.1782 + } else {
1.1783 + n = Math.abs(n);
1.1784 + }
1.1785 + return new File(dir, prefix + Long.toString(n) + suffix);
1.1786 + }
1.1787 + }
1.1788 +
1.1789 + /**
1.1790 + * <p> Creates a new empty file in the specified directory, using the
1.1791 + * given prefix and suffix strings to generate its name. If this method
1.1792 + * returns successfully then it is guaranteed that:
1.1793 + *
1.1794 + * <ol>
1.1795 + * <li> The file denoted by the returned abstract pathname did not exist
1.1796 + * before this method was invoked, and
1.1797 + * <li> Neither this method nor any of its variants will return the same
1.1798 + * abstract pathname again in the current invocation of the virtual
1.1799 + * machine.
1.1800 + * </ol>
1.1801 + *
1.1802 + * This method provides only part of a temporary-file facility. To arrange
1.1803 + * for a file created by this method to be deleted automatically, use the
1.1804 + * <code>{@link #deleteOnExit}</code> method.
1.1805 + *
1.1806 + * <p> The <code>prefix</code> argument must be at least three characters
1.1807 + * long. It is recommended that the prefix be a short, meaningful string
1.1808 + * such as <code>"hjb"</code> or <code>"mail"</code>. The
1.1809 + * <code>suffix</code> argument may be <code>null</code>, in which case the
1.1810 + * suffix <code>".tmp"</code> will be used.
1.1811 + *
1.1812 + * <p> To create the new file, the prefix and the suffix may first be
1.1813 + * adjusted to fit the limitations of the underlying platform. If the
1.1814 + * prefix is too long then it will be truncated, but its first three
1.1815 + * characters will always be preserved. If the suffix is too long then it
1.1816 + * too will be truncated, but if it begins with a period character
1.1817 + * (<code>'.'</code>) then the period and the first three characters
1.1818 + * following it will always be preserved. Once these adjustments have been
1.1819 + * made the name of the new file will be generated by concatenating the
1.1820 + * prefix, five or more internally-generated characters, and the suffix.
1.1821 + *
1.1822 + * <p> If the <code>directory</code> argument is <code>null</code> then the
1.1823 + * system-dependent default temporary-file directory will be used. The
1.1824 + * default temporary-file directory is specified by the system property
1.1825 + * <code>java.io.tmpdir</code>. On UNIX systems the default value of this
1.1826 + * property is typically <code>"/tmp"</code> or <code>"/var/tmp"</code>; on
1.1827 + * Microsoft Windows systems it is typically <code>"C:\\WINNT\\TEMP"</code>. A different
1.1828 + * value may be given to this system property when the Java virtual machine
1.1829 + * is invoked, but programmatic changes to this property are not guaranteed
1.1830 + * to have any effect upon the temporary directory used by this method.
1.1831 + *
1.1832 + * @param prefix The prefix string to be used in generating the file's
1.1833 + * name; must be at least three characters long
1.1834 + *
1.1835 + * @param suffix The suffix string to be used in generating the file's
1.1836 + * name; may be <code>null</code>, in which case the
1.1837 + * suffix <code>".tmp"</code> will be used
1.1838 + *
1.1839 + * @param directory The directory in which the file is to be created, or
1.1840 + * <code>null</code> if the default temporary-file
1.1841 + * directory is to be used
1.1842 + *
1.1843 + * @return An abstract pathname denoting a newly-created empty file
1.1844 + *
1.1845 + * @throws IllegalArgumentException
1.1846 + * If the <code>prefix</code> argument contains fewer than three
1.1847 + * characters
1.1848 + *
1.1849 + * @throws IOException If a file could not be created
1.1850 + *
1.1851 + * @throws SecurityException
1.1852 + * If a security manager exists and its <code>{@link
1.1853 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1854 + * method does not allow a file to be created
1.1855 + *
1.1856 + * @since 1.2
1.1857 + */
1.1858 + public static File createTempFile(String prefix, String suffix,
1.1859 + File directory)
1.1860 + throws IOException
1.1861 + {
1.1862 + if (prefix.length() < 3)
1.1863 + throw new IllegalArgumentException("Prefix string too short");
1.1864 + if (suffix == null)
1.1865 + suffix = ".tmp";
1.1866 +
1.1867 + File tmpdir = (directory != null) ? directory : TempDirectory.location();
1.1868 + SecurityManager sm = System.getSecurityManager();
1.1869 + File f;
1.1870 + do {
1.1871 + f = TempDirectory.generateFile(prefix, suffix, tmpdir);
1.1872 + if (sm != null) {
1.1873 + try {
1.1874 + sm.checkWrite(f.getPath());
1.1875 + } catch (SecurityException se) {
1.1876 + // don't reveal temporary directory location
1.1877 + if (directory == null)
1.1878 + throw new SecurityException("Unable to create temporary file");
1.1879 + throw se;
1.1880 + }
1.1881 + }
1.1882 + } while (!fs.createFileExclusively(f.getPath()));
1.1883 + return f;
1.1884 + }
1.1885 +
1.1886 + /**
1.1887 + * Creates an empty file in the default temporary-file directory, using
1.1888 + * the given prefix and suffix to generate its name. Invoking this method
1.1889 + * is equivalent to invoking <code>{@link #createTempFile(java.lang.String,
1.1890 + * java.lang.String, java.io.File)
1.1891 + * createTempFile(prefix, suffix, null)}</code>.
1.1892 + *
1.1893 + * <p> The {@link
1.1894 + * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[])
1.1895 + * Files.createTempFile} method provides an alternative method to create an
1.1896 + * empty file in the temporary-file directory. Files created by that method
1.1897 + * may have more restrictive access permissions to files created by this
1.1898 + * method and so may be more suited to security-sensitive applications.
1.1899 + *
1.1900 + * @param prefix The prefix string to be used in generating the file's
1.1901 + * name; must be at least three characters long
1.1902 + *
1.1903 + * @param suffix The suffix string to be used in generating the file's
1.1904 + * name; may be <code>null</code>, in which case the
1.1905 + * suffix <code>".tmp"</code> will be used
1.1906 + *
1.1907 + * @return An abstract pathname denoting a newly-created empty file
1.1908 + *
1.1909 + * @throws IllegalArgumentException
1.1910 + * If the <code>prefix</code> argument contains fewer than three
1.1911 + * characters
1.1912 + *
1.1913 + * @throws IOException If a file could not be created
1.1914 + *
1.1915 + * @throws SecurityException
1.1916 + * If a security manager exists and its <code>{@link
1.1917 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1.1918 + * method does not allow a file to be created
1.1919 + *
1.1920 + * @since 1.2
1.1921 + * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[])
1.1922 + */
1.1923 + public static File createTempFile(String prefix, String suffix)
1.1924 + throws IOException
1.1925 + {
1.1926 + return createTempFile(prefix, suffix, null);
1.1927 + }
1.1928 +
1.1929 + /* -- Basic infrastructure -- */
1.1930 +
1.1931 + /**
1.1932 + * Compares two abstract pathnames lexicographically. The ordering
1.1933 + * defined by this method depends upon the underlying system. On UNIX
1.1934 + * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
1.1935 + * systems it is not.
1.1936 + *
1.1937 + * @param pathname The abstract pathname to be compared to this abstract
1.1938 + * pathname
1.1939 + *
1.1940 + * @return Zero if the argument is equal to this abstract pathname, a
1.1941 + * value less than zero if this abstract pathname is
1.1942 + * lexicographically less than the argument, or a value greater
1.1943 + * than zero if this abstract pathname is lexicographically
1.1944 + * greater than the argument
1.1945 + *
1.1946 + * @since 1.2
1.1947 + */
1.1948 + public int compareTo(File pathname) {
1.1949 + return fs.compare(this, pathname);
1.1950 + }
1.1951 +
1.1952 + /**
1.1953 + * Tests this abstract pathname for equality with the given object.
1.1954 + * Returns <code>true</code> if and only if the argument is not
1.1955 + * <code>null</code> and is an abstract pathname that denotes the same file
1.1956 + * or directory as this abstract pathname. Whether or not two abstract
1.1957 + * pathnames are equal depends upon the underlying system. On UNIX
1.1958 + * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
1.1959 + * systems it is not.
1.1960 + *
1.1961 + * @param obj The object to be compared with this abstract pathname
1.1962 + *
1.1963 + * @return <code>true</code> if and only if the objects are the same;
1.1964 + * <code>false</code> otherwise
1.1965 + */
1.1966 + public boolean equals(Object obj) {
1.1967 + if ((obj != null) && (obj instanceof File)) {
1.1968 + return compareTo((File)obj) == 0;
1.1969 + }
1.1970 + return false;
1.1971 + }
1.1972 +
1.1973 + /**
1.1974 + * Computes a hash code for this abstract pathname. Because equality of
1.1975 + * abstract pathnames is inherently system-dependent, so is the computation
1.1976 + * of their hash codes. On UNIX systems, the hash code of an abstract
1.1977 + * pathname is equal to the exclusive <em>or</em> of the hash code
1.1978 + * of its pathname string and the decimal value
1.1979 + * <code>1234321</code>. On Microsoft Windows systems, the hash
1.1980 + * code is equal to the exclusive <em>or</em> of the hash code of
1.1981 + * its pathname string converted to lower case and the decimal
1.1982 + * value <code>1234321</code>. Locale is not taken into account on
1.1983 + * lowercasing the pathname string.
1.1984 + *
1.1985 + * @return A hash code for this abstract pathname
1.1986 + */
1.1987 + public int hashCode() {
1.1988 + return fs.hashCode(this);
1.1989 + }
1.1990 +
1.1991 + /**
1.1992 + * Returns the pathname string of this abstract pathname. This is just the
1.1993 + * string returned by the <code>{@link #getPath}</code> method.
1.1994 + *
1.1995 + * @return The string form of this abstract pathname
1.1996 + */
1.1997 + public String toString() {
1.1998 + return getPath();
1.1999 + }
1.2000 +
1.2001 + /**
1.2002 + * WriteObject is called to save this filename.
1.2003 + * The separator character is saved also so it can be replaced
1.2004 + * in case the path is reconstituted on a different host type.
1.2005 + * <p>
1.2006 + * @serialData Default fields followed by separator character.
1.2007 + */
1.2008 + private synchronized void writeObject(java.io.ObjectOutputStream s)
1.2009 + throws IOException
1.2010 + {
1.2011 + s.defaultWriteObject();
1.2012 + s.writeChar(this.separatorChar); // Add the separator character
1.2013 + }
1.2014 +
1.2015 + /**
1.2016 + * readObject is called to restore this filename.
1.2017 + * The original separator character is read. If it is different
1.2018 + * than the separator character on this system, then the old separator
1.2019 + * is replaced by the local separator.
1.2020 + */
1.2021 + private synchronized void readObject(java.io.ObjectInputStream s)
1.2022 + throws IOException, ClassNotFoundException
1.2023 + {
1.2024 + ObjectInputStream.GetField fields = s.readFields();
1.2025 + String pathField = (String)fields.get("path", null);
1.2026 + char sep = s.readChar(); // read the previous separator char
1.2027 + if (sep != separatorChar)
1.2028 + pathField = pathField.replace(sep, separatorChar);
1.2029 + this.path = fs.normalize(pathField);
1.2030 + this.prefixLength = fs.prefixLength(this.path);
1.2031 + }
1.2032 +
1.2033 + /** use serialVersionUID from JDK 1.0.2 for interoperability */
1.2034 + private static final long serialVersionUID = 301077366599181567L;
1.2035 +
1.2036 + // -- Integration with java.nio.file --
1.2037 +
1.2038 + private volatile transient Path filePath;
1.2039 +
1.2040 + /**
1.2041 + * Returns a {@link Path java.nio.file.Path} object constructed from the
1.2042 + * this abstract path. The resulting {@code Path} is associated with the
1.2043 + * {@link java.nio.file.FileSystems#getDefault default-filesystem}.
1.2044 + *
1.2045 + * <p> The first invocation of this method works as if invoking it were
1.2046 + * equivalent to evaluating the expression:
1.2047 + * <blockquote><pre>
1.2048 + * {@link java.nio.file.FileSystems#getDefault FileSystems.getDefault}().{@link
1.2049 + * java.nio.file.FileSystem#getPath getPath}(this.{@link #getPath getPath}());
1.2050 + * </pre></blockquote>
1.2051 + * Subsequent invocations of this method return the same {@code Path}.
1.2052 + *
1.2053 + * <p> If this abstract pathname is the empty abstract pathname then this
1.2054 + * method returns a {@code Path} that may be used to access the current
1.2055 + * user directory.
1.2056 + *
1.2057 + * @return a {@code Path} constructed from this abstract path
1.2058 + *
1.2059 + * @throws java.nio.file.InvalidPathException
1.2060 + * if a {@code Path} object cannot be constructed from the abstract
1.2061 + * path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
1.2062 + *
1.2063 + * @since 1.7
1.2064 + * @see Path#toFile
1.2065 + */
1.2066 + public Path toPath() {
1.2067 + Path result = filePath;
1.2068 + if (result == null) {
1.2069 + synchronized (this) {
1.2070 + result = filePath;
1.2071 + if (result == null) {
1.2072 + result = FileSystems.getDefault().getPath(path);
1.2073 + filePath = result;
1.2074 + }
1.2075 + }
1.2076 + }
1.2077 + return result;
1.2078 + }
1.2079 +}