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