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