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 inapplicable javadoc comment about special privileges. 741 /** 742 * Tests whether the application can read the file denoted by this 743 * abstract pathname. 744 * 745 * @return <code>true</code> if and only if the file specified by this 746 * abstract pathname exists <em>and</em> can be read by the 747 * application; <code>false</code> otherwise 748 * 749 * @throws SecurityException 750 * If a security manager exists and its <code>{@link 751 * java.lang.SecurityManager#checkRead(java.lang.String)}</code> 752 * method denies read access to the file 753 */ canRead()754 public boolean canRead() { 755 SecurityManager security = System.getSecurityManager(); 756 if (security != null) { 757 security.checkRead(path); 758 } 759 if (isInvalid()) { 760 return false; 761 } 762 return fs.checkAccess(this, FileSystem.ACCESS_READ); 763 } 764 765 // Android-changed: Removed inapplicable javadoc comment about special privileges. 766 /** 767 * Tests whether the application can modify the file denoted by this 768 * abstract pathname. 769 * 770 * @return <code>true</code> if and only if the file system actually 771 * contains a file denoted by this abstract pathname <em>and</em> 772 * the application is allowed to write to the file; 773 * <code>false</code> otherwise. 774 * 775 * @throws SecurityException 776 * If a security manager exists and its <code>{@link 777 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 778 * method denies write access to the file 779 */ canWrite()780 public boolean canWrite() { 781 SecurityManager security = System.getSecurityManager(); 782 if (security != null) { 783 security.checkWrite(path); 784 } 785 if (isInvalid()) { 786 return false; 787 } 788 return fs.checkAccess(this, FileSystem.ACCESS_WRITE); 789 } 790 791 /** 792 * Tests whether the file or directory denoted by this abstract pathname 793 * exists. 794 * 795 * @return <code>true</code> if and only if the file or directory denoted 796 * by this abstract pathname exists; <code>false</code> otherwise 797 * 798 * @throws SecurityException 799 * If a security manager exists and its <code>{@link 800 * java.lang.SecurityManager#checkRead(java.lang.String)}</code> 801 * method denies read access to the file or directory 802 */ exists()803 public boolean exists() { 804 SecurityManager security = System.getSecurityManager(); 805 if (security != null) { 806 security.checkRead(path); 807 } 808 if (isInvalid()) { 809 return false; 810 } 811 812 // Android-changed: b/25878034 work around SELinux stat64 denial. 813 return fs.checkAccess(this, FileSystem.ACCESS_OK); 814 } 815 816 /** 817 * Tests whether the file denoted by this abstract pathname is a 818 * directory. 819 * 820 * <p> Where it is required to distinguish an I/O exception from the case 821 * that the file is not a directory, or where several attributes of the 822 * same file are required at the same time, then the {@link 823 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[]) 824 * Files.readAttributes} method may be used. 825 * 826 * @return <code>true</code> if and only if the file denoted by this 827 * abstract pathname exists <em>and</em> is a directory; 828 * <code>false</code> otherwise 829 * 830 * @throws SecurityException 831 * If a security manager exists and its <code>{@link 832 * java.lang.SecurityManager#checkRead(java.lang.String)}</code> 833 * method denies read access to the file 834 */ isDirectory()835 public boolean isDirectory() { 836 SecurityManager security = System.getSecurityManager(); 837 if (security != null) { 838 security.checkRead(path); 839 } 840 if (isInvalid()) { 841 return false; 842 } 843 return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY) 844 != 0); 845 } 846 847 /** 848 * Tests whether the file denoted by this abstract pathname is a normal 849 * file. A file is <em>normal</em> if it is not a directory and, in 850 * addition, satisfies other system-dependent criteria. Any non-directory 851 * file created by a Java application is guaranteed to be a normal file. 852 * 853 * <p> Where it is required to distinguish an I/O exception from the case 854 * that the file is not a normal file, or where several attributes of the 855 * same file are required at the same time, then the {@link 856 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[]) 857 * Files.readAttributes} method may be used. 858 * 859 * @return <code>true</code> if and only if the file denoted by this 860 * abstract pathname exists <em>and</em> is a normal file; 861 * <code>false</code> otherwise 862 * 863 * @throws SecurityException 864 * If a security manager exists and its <code>{@link 865 * java.lang.SecurityManager#checkRead(java.lang.String)}</code> 866 * method denies read access to the file 867 */ isFile()868 public boolean isFile() { 869 SecurityManager security = System.getSecurityManager(); 870 if (security != null) { 871 security.checkRead(path); 872 } 873 if (isInvalid()) { 874 return false; 875 } 876 return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0); 877 } 878 879 /** 880 * Tests whether the file named by this abstract pathname is a hidden 881 * file. The exact definition of <em>hidden</em> is system-dependent. On 882 * UNIX systems, a file is considered to be hidden if its name begins with 883 * a period character (<code>'.'</code>). On Microsoft Windows systems, a file is 884 * considered to be hidden if it has been marked as such in the filesystem. 885 * 886 * @return <code>true</code> if and only if the file denoted by this 887 * abstract pathname is hidden according to the conventions of the 888 * underlying platform 889 * 890 * @throws SecurityException 891 * If a security manager exists and its <code>{@link 892 * java.lang.SecurityManager#checkRead(java.lang.String)}</code> 893 * method denies read access to the file 894 * 895 * @since 1.2 896 */ isHidden()897 public boolean isHidden() { 898 SecurityManager security = System.getSecurityManager(); 899 if (security != null) { 900 security.checkRead(path); 901 } 902 if (isInvalid()) { 903 return false; 904 } 905 return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0); 906 } 907 908 /** 909 * Returns the time that the file denoted by this abstract pathname was 910 * last modified. 911 * 912 * <p> Where it is required to distinguish an I/O exception from the case 913 * where {@code 0L} is returned, or where several attributes of the 914 * same file are required at the same time, or where the time of last 915 * access or the creation time are required, then the {@link 916 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[]) 917 * Files.readAttributes} method may be used. 918 * 919 * @return A <code>long</code> value representing the time the file was 920 * last modified, measured in milliseconds since the epoch 921 * (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the 922 * file does not exist or if an I/O error occurs 923 * 924 * @throws SecurityException 925 * If a security manager exists and its <code>{@link 926 * java.lang.SecurityManager#checkRead(java.lang.String)}</code> 927 * method denies read access to the file 928 */ lastModified()929 public long lastModified() { 930 SecurityManager security = System.getSecurityManager(); 931 if (security != null) { 932 security.checkRead(path); 933 } 934 if (isInvalid()) { 935 return 0L; 936 } 937 return fs.getLastModifiedTime(this); 938 } 939 940 /** 941 * Returns the length of the file denoted by this abstract pathname. 942 * The return value is unspecified if this pathname denotes a directory. 943 * 944 * <p> Where it is required to distinguish an I/O exception from the case 945 * that {@code 0L} is returned, or where several attributes of the same file 946 * are required at the same time, then the {@link 947 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[]) 948 * Files.readAttributes} method may be used. 949 * 950 * @return The length, in bytes, of the file denoted by this abstract 951 * pathname, or <code>0L</code> if the file does not exist. Some 952 * operating systems may return <code>0L</code> for pathnames 953 * denoting system-dependent entities such as devices or pipes. 954 * 955 * @throws SecurityException 956 * If a security manager exists and its <code>{@link 957 * java.lang.SecurityManager#checkRead(java.lang.String)}</code> 958 * method denies read access to the file 959 */ length()960 public long length() { 961 SecurityManager security = System.getSecurityManager(); 962 if (security != null) { 963 security.checkRead(path); 964 } 965 if (isInvalid()) { 966 return 0L; 967 } 968 return fs.getLength(this); 969 } 970 971 972 /* -- File operations -- */ 973 974 /** 975 * Atomically creates a new, empty file named by this abstract pathname if 976 * and only if a file with this name does not yet exist. The check for the 977 * existence of the file and the creation of the file if it does not exist 978 * are a single operation that is atomic with respect to all other 979 * filesystem activities that might affect the file. 980 * <P> 981 * Note: this method should <i>not</i> be used for file-locking, as 982 * the resulting protocol cannot be made to work reliably. The 983 * {@link java.nio.channels.FileLock FileLock} 984 * facility should be used instead. 985 * 986 * @return <code>true</code> if the named file does not exist and was 987 * successfully created; <code>false</code> if the named file 988 * already exists 989 * 990 * @throws IOException 991 * If an I/O error occurred 992 * 993 * @throws SecurityException 994 * If a security manager exists and its <code>{@link 995 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 996 * method denies write access to the file 997 * 998 * @since 1.2 999 */ createNewFile()1000 public boolean createNewFile() throws IOException { 1001 SecurityManager security = System.getSecurityManager(); 1002 if (security != null) security.checkWrite(path); 1003 if (isInvalid()) { 1004 throw new IOException("Invalid file path"); 1005 } 1006 return fs.createFileExclusively(path); 1007 } 1008 1009 /** 1010 * Deletes the file or directory denoted by this abstract pathname. If 1011 * this pathname denotes a directory, then the directory must be empty in 1012 * order to be deleted. 1013 * 1014 * <p> Note that the {@link java.nio.file.Files} class defines the {@link 1015 * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException} 1016 * when a file cannot be deleted. This is useful for error reporting and to 1017 * diagnose why a file cannot be deleted. 1018 * 1019 * @return <code>true</code> if and only if the file or directory is 1020 * successfully deleted; <code>false</code> otherwise 1021 * 1022 * @throws SecurityException 1023 * If a security manager exists and its <code>{@link 1024 * java.lang.SecurityManager#checkDelete}</code> method denies 1025 * delete access to the file 1026 */ delete()1027 public boolean delete() { 1028 SecurityManager security = System.getSecurityManager(); 1029 if (security != null) { 1030 security.checkDelete(path); 1031 } 1032 if (isInvalid()) { 1033 return false; 1034 } 1035 return fs.delete(this); 1036 } 1037 1038 // Android-added: Additional information about Android behaviour. 1039 /** 1040 * Requests that the file or directory denoted by this abstract 1041 * pathname be deleted when the virtual machine terminates. 1042 * Files (or directories) are deleted in the reverse order that 1043 * they are registered. Invoking this method to delete a file or 1044 * directory that is already registered for deletion has no effect. 1045 * Deletion will be attempted only for normal termination of the 1046 * virtual machine, as defined by the Java Language Specification. 1047 * 1048 * <p> Once deletion has been requested, it is not possible to cancel the 1049 * request. This method should therefore be used with care. 1050 * 1051 * <P> 1052 * Note: this method should <i>not</i> be used for file-locking, as 1053 * the resulting protocol cannot be made to work reliably. The 1054 * {@link java.nio.channels.FileLock FileLock} 1055 * facility should be used instead. 1056 * 1057 * <p><i>Note that on Android, the application lifecycle does not include VM termination, 1058 * so calling this method will not ensure that files are deleted</i>. Instead, you should 1059 * use the most appropriate out of: 1060 * <ul> 1061 * <li>Use a {@code finally} clause to manually invoke {@link #delete}. 1062 * <li>Maintain your own set of files to delete, and process it at an appropriate point 1063 * in your application's lifecycle. 1064 * <li>Use the Unix trick of deleting the file as soon as all readers and writers have 1065 * opened it. No new readers/writers will be able to access the file, but all existing 1066 * ones will still have access until the last one closes the file. 1067 * </ul> 1068 * 1069 * @throws SecurityException 1070 * If a security manager exists and its <code>{@link 1071 * java.lang.SecurityManager#checkDelete}</code> method denies 1072 * delete access to the file 1073 * 1074 * @see #delete 1075 * 1076 * @since 1.2 1077 */ deleteOnExit()1078 public void deleteOnExit() { 1079 SecurityManager security = System.getSecurityManager(); 1080 if (security != null) { 1081 security.checkDelete(path); 1082 } 1083 if (isInvalid()) { 1084 return; 1085 } 1086 DeleteOnExitHook.add(path); 1087 } 1088 1089 /** 1090 * Returns an array of strings naming the files and directories in the 1091 * directory denoted by this abstract pathname. 1092 * 1093 * <p> If this abstract pathname does not denote a directory, then this 1094 * method returns {@code null}. Otherwise an array of strings is 1095 * returned, one for each file or directory in the directory. Names 1096 * denoting the directory itself and the directory's parent directory are 1097 * not included in the result. Each string is a file name rather than a 1098 * complete path. 1099 * 1100 * <p> There is no guarantee that the name strings in the resulting array 1101 * will appear in any specific order; they are not, in particular, 1102 * guaranteed to appear in alphabetical order. 1103 * 1104 * <p> Note that the {@link java.nio.file.Files} class defines the {@link 1105 * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to 1106 * open a directory and iterate over the names of the files in the directory. 1107 * This may use less resources when working with very large directories, and 1108 * may be more responsive when working with remote directories. 1109 * 1110 * @return An array of strings naming the files and directories in the 1111 * directory denoted by this abstract pathname. The array will be 1112 * empty if the directory is empty. Returns {@code null} if 1113 * this abstract pathname does not denote a directory, or if an 1114 * I/O error occurs. 1115 * 1116 * @throws SecurityException 1117 * If a security manager exists and its {@link 1118 * SecurityManager#checkRead(String)} method denies read access to 1119 * the directory 1120 */ list()1121 public String[] list() { 1122 SecurityManager security = System.getSecurityManager(); 1123 if (security != null) { 1124 security.checkRead(path); 1125 } 1126 if (isInvalid()) { 1127 return null; 1128 } 1129 return fs.list(this); 1130 } 1131 1132 /** 1133 * Returns an array of strings naming the files and directories in the 1134 * directory denoted by this abstract pathname that satisfy the specified 1135 * filter. The behavior of this method is the same as that of the 1136 * {@link #list()} method, except that the strings in the returned array 1137 * must satisfy the filter. If the given {@code filter} is {@code null} 1138 * then all names are accepted. Otherwise, a name satisfies the filter if 1139 * and only if the value {@code true} results when the {@link 1140 * FilenameFilter#accept FilenameFilter.accept(File, String)} method 1141 * of the filter is invoked on this abstract pathname and the name of a 1142 * file or directory in the directory that it denotes. 1143 * 1144 * @param filter 1145 * A filename filter 1146 * 1147 * @return An array of strings naming the files and directories in the 1148 * directory denoted by this abstract pathname that were accepted 1149 * by the given {@code filter}. The array will be empty if the 1150 * directory is empty or if no names were accepted by the filter. 1151 * Returns {@code null} if this abstract pathname does not denote 1152 * a directory, or if an I/O error occurs. 1153 * 1154 * @throws SecurityException 1155 * If a security manager exists and its {@link 1156 * SecurityManager#checkRead(String)} method denies read access to 1157 * the directory 1158 * 1159 * @see java.nio.file.Files#newDirectoryStream(Path,String) 1160 */ list(FilenameFilter filter)1161 public String[] list(FilenameFilter filter) { 1162 String names[] = list(); 1163 if ((names == null) || (filter == null)) { 1164 return names; 1165 } 1166 List<String> v = new ArrayList<>(); 1167 for (int i = 0 ; i < names.length ; i++) { 1168 if (filter.accept(this, names[i])) { 1169 v.add(names[i]); 1170 } 1171 } 1172 return v.toArray(new String[v.size()]); 1173 } 1174 1175 /** 1176 * Returns an array of abstract pathnames denoting the files in the 1177 * directory denoted by this abstract pathname. 1178 * 1179 * <p> If this abstract pathname does not denote a directory, then this 1180 * method returns {@code null}. Otherwise an array of {@code File} objects 1181 * is returned, one for each file or directory in the directory. Pathnames 1182 * denoting the directory itself and the directory's parent directory are 1183 * not included in the result. Each resulting abstract pathname is 1184 * constructed from this abstract pathname using the {@link #File(File, 1185 * String) File(File, String)} constructor. Therefore if this 1186 * pathname is absolute then each resulting pathname is absolute; if this 1187 * pathname is relative then each resulting pathname will be relative to 1188 * the same directory. 1189 * 1190 * <p> There is no guarantee that the name strings in the resulting array 1191 * will appear in any specific order; they are not, in particular, 1192 * guaranteed to appear in alphabetical order. 1193 * 1194 * <p> Note that the {@link java.nio.file.Files} class defines the {@link 1195 * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method 1196 * to open a directory and iterate over the names of the files in the 1197 * directory. This may use less resources when working with very large 1198 * directories. 1199 * 1200 * @return An array of abstract pathnames denoting the files and 1201 * directories in the directory denoted by this abstract pathname. 1202 * The array will be empty if the directory is empty. Returns 1203 * {@code null} if this abstract pathname does not denote a 1204 * directory, or if an I/O error occurs. 1205 * 1206 * @throws SecurityException 1207 * If a security manager exists and its {@link 1208 * SecurityManager#checkRead(String)} method denies read access to 1209 * the directory 1210 * 1211 * @since 1.2 1212 */ listFiles()1213 public File[] listFiles() { 1214 String[] ss = list(); 1215 if (ss == null) return null; 1216 int n = ss.length; 1217 File[] fs = new File[n]; 1218 for (int i = 0; i < n; i++) { 1219 fs[i] = new File(ss[i], this); 1220 } 1221 return fs; 1222 } 1223 1224 /** 1225 * Returns an array of abstract pathnames denoting the files and 1226 * directories in the directory denoted by this abstract pathname that 1227 * satisfy the specified filter. The behavior of this method is the same 1228 * as that of the {@link #listFiles()} method, except that the pathnames in 1229 * the returned array must satisfy the filter. If the given {@code filter} 1230 * is {@code null} then all pathnames are accepted. Otherwise, a pathname 1231 * satisfies the filter if and only if the value {@code true} results when 1232 * the {@link FilenameFilter#accept 1233 * FilenameFilter.accept(File, String)} method of the filter is 1234 * invoked on this abstract pathname and the name of a file or directory in 1235 * the directory that it denotes. 1236 * 1237 * @param filter 1238 * A filename filter 1239 * 1240 * @return An array of abstract pathnames denoting the files and 1241 * directories in the directory denoted by this abstract pathname. 1242 * The array will be empty if the directory is empty. Returns 1243 * {@code null} if this abstract pathname does not denote a 1244 * directory, or if an I/O error occurs. 1245 * 1246 * @throws SecurityException 1247 * If a security manager exists and its {@link 1248 * SecurityManager#checkRead(String)} method denies read access to 1249 * the directory 1250 * 1251 * @since 1.2 1252 * @see java.nio.file.Files#newDirectoryStream(Path,String) 1253 */ listFiles(FilenameFilter filter)1254 public File[] listFiles(FilenameFilter filter) { 1255 String ss[] = list(); 1256 if (ss == null) return null; 1257 ArrayList<File> files = new ArrayList<>(); 1258 for (String s : ss) 1259 if ((filter == null) || filter.accept(this, s)) 1260 files.add(new File(s, this)); 1261 return files.toArray(new File[files.size()]); 1262 } 1263 1264 /** 1265 * Returns an array of abstract pathnames denoting the files and 1266 * directories in the directory denoted by this abstract pathname that 1267 * satisfy the specified filter. The behavior of this method is the same 1268 * as that of the {@link #listFiles()} method, except that the pathnames in 1269 * the returned array must satisfy the filter. If the given {@code filter} 1270 * is {@code null} then all pathnames are accepted. Otherwise, a pathname 1271 * satisfies the filter if and only if the value {@code true} results when 1272 * the {@link FileFilter#accept FileFilter.accept(File)} method of the 1273 * filter is invoked on the pathname. 1274 * 1275 * @param filter 1276 * A file filter 1277 * 1278 * @return An array of abstract pathnames denoting the files and 1279 * directories in the directory denoted by this abstract pathname. 1280 * The array will be empty if the directory is empty. Returns 1281 * {@code null} if this abstract pathname does not denote a 1282 * directory, or if an I/O error occurs. 1283 * 1284 * @throws SecurityException 1285 * If a security manager exists and its {@link 1286 * SecurityManager#checkRead(String)} method denies read access to 1287 * the directory 1288 * 1289 * @since 1.2 1290 * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter) 1291 */ listFiles(FileFilter filter)1292 public File[] listFiles(FileFilter filter) { 1293 String ss[] = list(); 1294 if (ss == null) return null; 1295 ArrayList<File> files = new ArrayList<>(); 1296 for (String s : ss) { 1297 File f = new File(s, this); 1298 if ((filter == null) || filter.accept(f)) 1299 files.add(f); 1300 } 1301 return files.toArray(new File[files.size()]); 1302 } 1303 1304 /** 1305 * Creates the directory named by this abstract pathname. 1306 * 1307 * @return <code>true</code> if and only if the directory was 1308 * created; <code>false</code> otherwise 1309 * 1310 * @throws SecurityException 1311 * If a security manager exists and its <code>{@link 1312 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1313 * method does not permit the named directory to be created 1314 */ mkdir()1315 public boolean mkdir() { 1316 SecurityManager security = System.getSecurityManager(); 1317 if (security != null) { 1318 security.checkWrite(path); 1319 } 1320 if (isInvalid()) { 1321 return false; 1322 } 1323 return fs.createDirectory(this); 1324 } 1325 1326 /** 1327 * Creates the directory named by this abstract pathname, including any 1328 * necessary but nonexistent parent directories. Note that if this 1329 * operation fails it may have succeeded in creating some of the necessary 1330 * parent directories. 1331 * 1332 * @return <code>true</code> if and only if the directory was created, 1333 * along with all necessary parent directories; <code>false</code> 1334 * otherwise 1335 * 1336 * @throws SecurityException 1337 * If a security manager exists and its <code>{@link 1338 * java.lang.SecurityManager#checkRead(java.lang.String)}</code> 1339 * method does not permit verification of the existence of the 1340 * named directory and all necessary parent directories; or if 1341 * the <code>{@link 1342 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1343 * method does not permit the named directory and all necessary 1344 * parent directories to be created 1345 */ mkdirs()1346 public boolean mkdirs() { 1347 if (exists()) { 1348 return false; 1349 } 1350 if (mkdir()) { 1351 return true; 1352 } 1353 File canonFile = null; 1354 try { 1355 canonFile = getCanonicalFile(); 1356 } catch (IOException e) { 1357 return false; 1358 } 1359 1360 File parent = canonFile.getParentFile(); 1361 return (parent != null && (parent.mkdirs() || parent.exists()) && 1362 canonFile.mkdir()); 1363 } 1364 1365 // Android-changed: Replaced generic platform info with Android specific one. 1366 /** 1367 * Renames the file denoted by this abstract pathname. 1368 * 1369 * <p>Many failures are possible. Some of the more likely failures include: 1370 * <ul> 1371 * <li>Write permission is required on the directories containing both the source and 1372 * destination paths. 1373 * <li>Search permission is required for all parents of both paths. 1374 * <li>Both paths be on the same mount point. On Android, applications are most likely to hit 1375 * this restriction when attempting to copy between internal storage and an SD card. 1376 * </ul> 1377 * 1378 * <p>The return value should always be checked to make sure 1379 * that the rename operation was successful. 1380 * 1381 * <p> Note that the {@link java.nio.file.Files} class defines the {@link 1382 * java.nio.file.Files#move move} method to move or rename a file in a 1383 * platform independent manner. 1384 * 1385 * @param dest The new abstract pathname for the named file 1386 * 1387 * @return <code>true</code> if and only if the renaming succeeded; 1388 * <code>false</code> otherwise 1389 * 1390 * @throws SecurityException 1391 * If a security manager exists and its <code>{@link 1392 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1393 * method denies write access to either the old or new pathnames 1394 * 1395 * @throws NullPointerException 1396 * If parameter <code>dest</code> is <code>null</code> 1397 */ renameTo(File dest)1398 public boolean renameTo(File dest) { 1399 SecurityManager security = System.getSecurityManager(); 1400 if (security != null) { 1401 security.checkWrite(path); 1402 security.checkWrite(dest.path); 1403 } 1404 if (dest == null) { 1405 throw new NullPointerException(); 1406 } 1407 if (this.isInvalid() || dest.isInvalid()) { 1408 return false; 1409 } 1410 return fs.rename(this, dest); 1411 } 1412 1413 /** 1414 * Sets the last-modified time of the file or directory named by this 1415 * abstract pathname. 1416 * 1417 * <p> All platforms support file-modification times to the nearest second, 1418 * but some provide more precision. The argument will be truncated to fit 1419 * the supported precision. If the operation succeeds and no intervening 1420 * operations on the file take place, then the next invocation of the 1421 * <code>{@link #lastModified}</code> method will return the (possibly 1422 * truncated) <code>time</code> argument that was passed to this method. 1423 * 1424 * @param time The new last-modified time, measured in milliseconds since 1425 * the epoch (00:00:00 GMT, January 1, 1970) 1426 * 1427 * @return <code>true</code> if and only if the operation succeeded; 1428 * <code>false</code> otherwise 1429 * 1430 * @throws IllegalArgumentException If the argument is negative 1431 * 1432 * @throws SecurityException 1433 * If a security manager exists and its <code>{@link 1434 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1435 * method denies write access to the named file 1436 * 1437 * @since 1.2 1438 */ setLastModified(long time)1439 public boolean setLastModified(long time) { 1440 if (time < 0) throw new IllegalArgumentException("Negative time"); 1441 SecurityManager security = System.getSecurityManager(); 1442 if (security != null) { 1443 security.checkWrite(path); 1444 } 1445 if (isInvalid()) { 1446 return false; 1447 } 1448 return fs.setLastModifiedTime(this, time); 1449 } 1450 1451 // Android-changed: Removed inapplicable javadoc comment about special privileges. 1452 /** 1453 * Marks the file or directory named by this abstract pathname so that 1454 * only read operations are allowed. After invoking this method the file 1455 * or directory will not change until it is either deleted or marked 1456 * to allow write access. Whether or not a read-only file or 1457 * directory may be deleted depends upon the underlying system. 1458 * 1459 * @return <code>true</code> if and only if the operation succeeded; 1460 * <code>false</code> otherwise 1461 * 1462 * @throws SecurityException 1463 * If a security manager exists and its <code>{@link 1464 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1465 * method denies write access to the named file 1466 * 1467 * @since 1.2 1468 */ setReadOnly()1469 public boolean setReadOnly() { 1470 SecurityManager security = System.getSecurityManager(); 1471 if (security != null) { 1472 security.checkWrite(path); 1473 } 1474 if (isInvalid()) { 1475 return false; 1476 } 1477 return fs.setReadOnly(this); 1478 } 1479 1480 // Android-changed: Removed inapplicable javadoc comment about special privileges. 1481 /** 1482 * Sets the owner's or everybody's write permission for this abstract 1483 * pathname. 1484 * 1485 * <p> The {@link java.nio.file.Files} class defines methods that operate on 1486 * file attributes including file permissions. This may be used when finer 1487 * manipulation of file permissions is required. 1488 * 1489 * @param writable 1490 * If <code>true</code>, sets the access permission to allow write 1491 * operations; if <code>false</code> to disallow write operations 1492 * 1493 * @param ownerOnly 1494 * If <code>true</code>, the write permission applies only to the 1495 * owner's write permission; otherwise, it applies to everybody. If 1496 * the underlying file system can not distinguish the owner's write 1497 * permission from that of others, then the permission will apply to 1498 * everybody, regardless of this value. 1499 * 1500 * @return <code>true</code> if and only if the operation succeeded. The 1501 * operation will fail if the user does not have permission to change 1502 * the access permissions of this abstract pathname. 1503 * 1504 * @throws SecurityException 1505 * If a security manager exists and its <code>{@link 1506 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1507 * method denies write access to the named file 1508 * 1509 * @since 1.6 1510 */ setWritable(boolean writable, boolean ownerOnly)1511 public boolean setWritable(boolean writable, boolean ownerOnly) { 1512 SecurityManager security = System.getSecurityManager(); 1513 if (security != null) { 1514 security.checkWrite(path); 1515 } 1516 if (isInvalid()) { 1517 return false; 1518 } 1519 return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly); 1520 } 1521 1522 // Android-changed: Removed inapplicable javadoc comment about special privileges. 1523 /** 1524 * A convenience method to set the owner's write permission for this abstract 1525 * pathname. 1526 * 1527 * <p> An invocation of this method of the form <tt>file.setWritable(arg)</tt> 1528 * behaves in exactly the same way as the invocation 1529 * 1530 * <pre> 1531 * file.setWritable(arg, true) </pre> 1532 * 1533 * @param writable 1534 * If <code>true</code>, sets the access permission to allow write 1535 * operations; if <code>false</code> to disallow write operations 1536 * 1537 * @return <code>true</code> if and only if the operation succeeded. The 1538 * operation will fail if the user does not have permission to 1539 * change the access permissions of this abstract pathname. 1540 * 1541 * @throws SecurityException 1542 * If a security manager exists and its <code>{@link 1543 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1544 * method denies write access to the file 1545 * 1546 * @since 1.6 1547 */ setWritable(boolean writable)1548 public boolean setWritable(boolean writable) { 1549 return setWritable(writable, true); 1550 } 1551 1552 // Android-changed: Removed inapplicable javadoc comment about special privileges. 1553 /** 1554 * Sets the owner's or everybody's read permission for this abstract 1555 * pathname. 1556 * 1557 * <p> The {@link java.nio.file.Files} class defines methods that operate on 1558 * file attributes including file permissions. This may be used when finer 1559 * manipulation of file permissions is required. 1560 * 1561 * @param readable 1562 * If <code>true</code>, sets the access permission to allow read 1563 * operations; if <code>false</code> to disallow read operations 1564 * 1565 * @param ownerOnly 1566 * If <code>true</code>, the read permission applies only to the 1567 * owner's read permission; otherwise, it applies to everybody. If 1568 * the underlying file system can not distinguish the owner's read 1569 * permission from that of others, then the permission will apply to 1570 * everybody, regardless of this value. 1571 * 1572 * @return <code>true</code> if and only if the operation succeeded. The 1573 * operation will fail if the user does not have permission to 1574 * change the access permissions of this abstract pathname. If 1575 * <code>readable</code> is <code>false</code> and the underlying 1576 * file system does not implement a read permission, then the 1577 * operation will fail. 1578 * 1579 * @throws SecurityException 1580 * If a security manager exists and its <code>{@link 1581 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1582 * method denies write access to the file 1583 * 1584 * @since 1.6 1585 */ setReadable(boolean readable, boolean ownerOnly)1586 public boolean setReadable(boolean readable, boolean ownerOnly) { 1587 SecurityManager security = System.getSecurityManager(); 1588 if (security != null) { 1589 security.checkWrite(path); 1590 } 1591 if (isInvalid()) { 1592 return false; 1593 } 1594 return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly); 1595 } 1596 1597 // Android-changed: Removed inapplicable javadoc comment about special privileges. 1598 /** 1599 * A convenience method to set the owner's read permission for this abstract 1600 * pathname. 1601 * 1602 * <p>An invocation of this method of the form <tt>file.setReadable(arg)</tt> 1603 * behaves in exactly the same way as the invocation 1604 * 1605 * <pre> 1606 * file.setReadable(arg, true) </pre> 1607 * 1608 * @param readable 1609 * If <code>true</code>, sets the access permission to allow read 1610 * operations; if <code>false</code> to disallow read operations 1611 * 1612 * @return <code>true</code> if and only if the operation succeeded. The 1613 * operation will fail if the user does not have permission to 1614 * change the access permissions of this abstract pathname. If 1615 * <code>readable</code> is <code>false</code> and the underlying 1616 * file system does not implement a read permission, then the 1617 * operation will fail. 1618 * 1619 * @throws SecurityException 1620 * If a security manager exists and its <code>{@link 1621 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1622 * method denies write access to the file 1623 * 1624 * @since 1.6 1625 */ setReadable(boolean readable)1626 public boolean setReadable(boolean readable) { 1627 return setReadable(readable, true); 1628 } 1629 1630 // Android-changed: Removed inapplicable javadoc comment about special privileges. 1631 /** 1632 * Sets the owner's or everybody's execute permission for this abstract 1633 * pathname. 1634 * 1635 * <p> The {@link java.nio.file.Files} class defines methods that operate on 1636 * file attributes including file permissions. This may be used when finer 1637 * manipulation of file permissions is required. 1638 * 1639 * @param executable 1640 * If <code>true</code>, sets the access permission to allow execute 1641 * operations; if <code>false</code> to disallow execute operations 1642 * 1643 * @param ownerOnly 1644 * If <code>true</code>, the execute permission applies only to the 1645 * owner's execute permission; otherwise, it applies to everybody. 1646 * If the underlying file system can not distinguish the owner's 1647 * execute permission from that of others, then the permission will 1648 * apply to everybody, regardless of this value. 1649 * 1650 * @return <code>true</code> if and only if the operation succeeded. The 1651 * operation will fail if the user does not have permission to 1652 * change the access permissions of this abstract pathname. If 1653 * <code>executable</code> is <code>false</code> and the underlying 1654 * file system does not implement an execute permission, then the 1655 * operation will fail. 1656 * 1657 * @throws SecurityException 1658 * If a security manager exists and its <code>{@link 1659 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1660 * method denies write access to the file 1661 * 1662 * @since 1.6 1663 */ setExecutable(boolean executable, boolean ownerOnly)1664 public boolean setExecutable(boolean executable, boolean ownerOnly) { 1665 SecurityManager security = System.getSecurityManager(); 1666 if (security != null) { 1667 security.checkWrite(path); 1668 } 1669 if (isInvalid()) { 1670 return false; 1671 } 1672 return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly); 1673 } 1674 1675 // Android-changed: Removed inapplicable javadoc comment about special privileges. 1676 /** 1677 * A convenience method to set the owner's execute permission for this 1678 * abstract pathname. 1679 * 1680 * <p>An invocation of this method of the form <tt>file.setExcutable(arg)</tt> 1681 * behaves in exactly the same way as the invocation 1682 * 1683 * <pre> 1684 * file.setExecutable(arg, true) </pre> 1685 * 1686 * @param executable 1687 * If <code>true</code>, sets the access permission to allow execute 1688 * operations; if <code>false</code> to disallow execute operations 1689 * 1690 * @return <code>true</code> if and only if the operation succeeded. The 1691 * operation will fail if the user does not have permission to 1692 * change the access permissions of this abstract pathname. If 1693 * <code>executable</code> is <code>false</code> and the underlying 1694 * file system does not implement an execute permission, then the 1695 * operation will fail. 1696 * 1697 * @throws SecurityException 1698 * If a security manager exists and its <code>{@link 1699 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1700 * method denies write access to the file 1701 * 1702 * @since 1.6 1703 */ setExecutable(boolean executable)1704 public boolean setExecutable(boolean executable) { 1705 return setExecutable(executable, true); 1706 } 1707 1708 // Android-changed: Removed inapplicable javadoc comment about special privileges. 1709 /** 1710 * Tests whether the application can execute the file denoted by this 1711 * abstract pathname. 1712 * 1713 * @return <code>true</code> if and only if the abstract pathname exists 1714 * <em>and</em> the application is allowed to execute the file 1715 * 1716 * @throws SecurityException 1717 * If a security manager exists and its <code>{@link 1718 * java.lang.SecurityManager#checkExec(java.lang.String)}</code> 1719 * method denies execute access to the file 1720 * 1721 * @since 1.6 1722 */ canExecute()1723 public boolean canExecute() { 1724 SecurityManager security = System.getSecurityManager(); 1725 if (security != null) { 1726 security.checkExec(path); 1727 } 1728 if (isInvalid()) { 1729 return false; 1730 } 1731 return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE); 1732 } 1733 1734 1735 /* -- Filesystem interface -- */ 1736 1737 // Android-changed: Replaced generic platform info with Android specific one. 1738 /** 1739 * Returns the file system roots. On Android and other Unix systems, there is 1740 * a single root, {@code /}. 1741 */ listRoots()1742 public static File[] listRoots() { 1743 return fs.listRoots(); 1744 } 1745 1746 1747 /* -- Disk usage -- */ 1748 1749 /** 1750 * Returns the size of the partition <a href="#partName">named</a> by this 1751 * abstract pathname. 1752 * 1753 * @return The size, in bytes, of the partition or <tt>0L</tt> if this 1754 * abstract pathname does not name a partition 1755 * 1756 * @throws SecurityException 1757 * If a security manager has been installed and it denies 1758 * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt> 1759 * or its {@link SecurityManager#checkRead(String)} method denies 1760 * read access to the file named by this abstract pathname 1761 * 1762 * @since 1.6 1763 */ getTotalSpace()1764 public long getTotalSpace() { 1765 SecurityManager sm = System.getSecurityManager(); 1766 if (sm != null) { 1767 sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); 1768 sm.checkRead(path); 1769 } 1770 if (isInvalid()) { 1771 return 0L; 1772 } 1773 return fs.getSpace(this, FileSystem.SPACE_TOTAL); 1774 } 1775 1776 /** 1777 * Returns the number of unallocated bytes in the partition <a 1778 * href="#partName">named</a> by this abstract path name. 1779 * 1780 * <p> The returned number of unallocated bytes is a hint, but not 1781 * a guarantee, that it is possible to use most or any of these 1782 * bytes. The number of unallocated bytes is most likely to be 1783 * accurate immediately after this call. It is likely to be made 1784 * inaccurate by any external I/O operations including those made 1785 * on the system outside of this virtual machine. This method 1786 * makes no guarantee that write operations to this file system 1787 * will succeed. 1788 * 1789 * @return The number of unallocated bytes on the partition or <tt>0L</tt> 1790 * if the abstract pathname does not name a partition. This 1791 * value will be less than or equal to the total file system size 1792 * returned by {@link #getTotalSpace}. 1793 * 1794 * @throws SecurityException 1795 * If a security manager has been installed and it denies 1796 * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt> 1797 * or its {@link SecurityManager#checkRead(String)} method denies 1798 * read access to the file named by this abstract pathname 1799 * 1800 * @since 1.6 1801 */ getFreeSpace()1802 public long getFreeSpace() { 1803 SecurityManager sm = System.getSecurityManager(); 1804 if (sm != null) { 1805 sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); 1806 sm.checkRead(path); 1807 } 1808 if (isInvalid()) { 1809 return 0L; 1810 } 1811 return fs.getSpace(this, FileSystem.SPACE_FREE); 1812 } 1813 1814 // Android-added: Replaced generic platform info with Android specific one. 1815 /** 1816 * Returns the number of bytes available to this virtual machine on the 1817 * partition <a href="#partName">named</a> by this abstract pathname. When 1818 * possible, this method checks for write permissions and other operating 1819 * system restrictions and will therefore usually provide a more accurate 1820 * estimate of how much new data can actually be written than {@link 1821 * #getFreeSpace}. 1822 * 1823 * <p> The returned number of available bytes is a hint, but not a 1824 * guarantee, that it is possible to use most or any of these bytes. The 1825 * number of unallocated bytes is most likely to be accurate immediately 1826 * after this call. It is likely to be made inaccurate by any external 1827 * I/O operations including those made on the system outside of this 1828 * virtual machine. This method makes no guarantee that write operations 1829 * to this file system will succeed. 1830 * 1831 * <p> On Android (and other Unix-based systems), this method returns the number of free bytes 1832 * available to non-root users, regardless of whether you're actually running as root, 1833 * and regardless of any quota or other restrictions that might apply to the user. 1834 * (The {@code getFreeSpace} method returns the number of bytes potentially available to root.) 1835 * 1836 * @return The number of available bytes on the partition or <tt>0L</tt> 1837 * if the abstract pathname does not name a partition. On 1838 * systems where this information is not available, this method 1839 * will be equivalent to a call to {@link #getFreeSpace}. 1840 * 1841 * @throws SecurityException 1842 * If a security manager has been installed and it denies 1843 * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt> 1844 * or its {@link SecurityManager#checkRead(String)} method denies 1845 * read access to the file named by this abstract pathname 1846 * 1847 * @since 1.6 1848 */ getUsableSpace()1849 public long getUsableSpace() { 1850 SecurityManager sm = System.getSecurityManager(); 1851 if (sm != null) { 1852 sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); 1853 sm.checkRead(path); 1854 } 1855 if (isInvalid()) { 1856 return 0L; 1857 } 1858 return fs.getSpace(this, FileSystem.SPACE_USABLE); 1859 } 1860 1861 /* -- Temporary files -- */ 1862 1863 private static class TempDirectory { TempDirectory()1864 private TempDirectory() { } 1865 1866 // Android-changed: Don't cache java.io.tmpdir value temporary directory location. 1867 /* 1868 private static final File tmpdir = new File(AccessController 1869 .doPrivileged(new GetPropertyAction("java.io.tmpdir"))); 1870 static File location() { 1871 return tmpdir; 1872 } 1873 */ 1874 1875 // file name generation 1876 // private static final SecureRandom random = new SecureRandom(); generateFile(String prefix, String suffix, File dir)1877 static File generateFile(String prefix, String suffix, File dir) 1878 throws IOException 1879 { 1880 // Android-changed: Use Math.randomIntInternal. 1881 // This (pseudo) random number is initialized post-fork. 1882 1883 long n = Math.randomLongInternal(); 1884 if (n == Long.MIN_VALUE) { 1885 n = 0; // corner case 1886 } else { 1887 n = Math.abs(n); 1888 } 1889 1890 // Android-changed: Reject invalid file prefixes. 1891 // Use only the file name from the supplied prefix 1892 // prefix = (new File(prefix)).getName(); 1893 1894 String name = prefix + Long.toString(n) + suffix; 1895 File f = new File(dir, name); 1896 if (!name.equals(f.getName()) || f.isInvalid()) { 1897 if (System.getSecurityManager() != null) 1898 throw new IOException("Unable to create temporary file"); 1899 else 1900 throw new IOException("Unable to create temporary file, " + f); 1901 } 1902 return f; 1903 } 1904 } 1905 1906 /** 1907 * <p> Creates a new empty file in the specified directory, using the 1908 * given prefix and suffix strings to generate its name. If this method 1909 * returns successfully then it is guaranteed that: 1910 * 1911 * <ol> 1912 * <li> The file denoted by the returned abstract pathname did not exist 1913 * before this method was invoked, and 1914 * <li> Neither this method nor any of its variants will return the same 1915 * abstract pathname again in the current invocation of the virtual 1916 * machine. 1917 * </ol> 1918 * 1919 * This method provides only part of a temporary-file facility. To arrange 1920 * for a file created by this method to be deleted automatically, use the 1921 * <code>{@link #deleteOnExit}</code> method. 1922 * 1923 * <p> The <code>prefix</code> argument must be at least three characters 1924 * long. It is recommended that the prefix be a short, meaningful string 1925 * such as <code>"hjb"</code> or <code>"mail"</code>. The 1926 * <code>suffix</code> argument may be <code>null</code>, in which case the 1927 * suffix <code>".tmp"</code> will be used. 1928 * 1929 * <p> To create the new file, the prefix and the suffix may first be 1930 * adjusted to fit the limitations of the underlying platform. If the 1931 * prefix is too long then it will be truncated, but its first three 1932 * characters will always be preserved. If the suffix is too long then it 1933 * too will be truncated, but if it begins with a period character 1934 * (<code>'.'</code>) then the period and the first three characters 1935 * following it will always be preserved. Once these adjustments have been 1936 * made the name of the new file will be generated by concatenating the 1937 * prefix, five or more internally-generated characters, and the suffix. 1938 * 1939 * <p> If the <code>directory</code> argument is <code>null</code> then the 1940 * system-dependent default temporary-file directory will be used. The 1941 * default temporary-file directory is specified by the system property 1942 * <code>java.io.tmpdir</code>. On UNIX systems the default value of this 1943 * property is typically <code>"/tmp"</code> or <code>"/var/tmp"</code>; on 1944 * Microsoft Windows systems it is typically <code>"C:\\WINNT\\TEMP"</code>. A different 1945 * value may be given to this system property when the Java virtual machine 1946 * is invoked, but programmatic changes to this property are not guaranteed 1947 * to have any effect upon the temporary directory used by this method. 1948 * 1949 * @param prefix The prefix string to be used in generating the file's 1950 * name; must be at least three characters long 1951 * 1952 * @param suffix The suffix string to be used in generating the file's 1953 * name; may be <code>null</code>, in which case the 1954 * suffix <code>".tmp"</code> will be used 1955 * 1956 * @param directory The directory in which the file is to be created, or 1957 * <code>null</code> if the default temporary-file 1958 * directory is to be used 1959 * 1960 * @return An abstract pathname denoting a newly-created empty file 1961 * 1962 * @throws IllegalArgumentException 1963 * If the <code>prefix</code> argument contains fewer than three 1964 * characters 1965 * 1966 * @throws IOException If a file could not be created 1967 * 1968 * @throws SecurityException 1969 * If a security manager exists and its <code>{@link 1970 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 1971 * method does not allow a file to be created 1972 * 1973 * @since 1.2 1974 */ createTempFile(String prefix, String suffix, File directory)1975 public static File createTempFile(String prefix, String suffix, 1976 File directory) 1977 throws IOException 1978 { 1979 if (prefix.length() < 3) 1980 throw new IllegalArgumentException("Prefix string too short"); 1981 if (suffix == null) 1982 suffix = ".tmp"; 1983 1984 // Android-changed: Handle java.io.tmpdir changes. 1985 File tmpdir = (directory != null) ? directory 1986 : new File(System.getProperty("java.io.tmpdir", ".")); 1987 //SecurityManager sm = System.getSecurityManager(); 1988 File f; 1989 do { 1990 f = TempDirectory.generateFile(prefix, suffix, tmpdir); 1991 1992 // Android-changed: sm is always null on Android. 1993 /* 1994 if (sm != null) { 1995 try { 1996 sm.checkWrite(f.getPath()); 1997 } catch (SecurityException se) { 1998 // don't reveal temporary directory location 1999 if (directory == null) 2000 throw new SecurityException("Unable to create temporary file"); 2001 throw se; 2002 } 2003 } 2004 */ 2005 } while ((fs.getBooleanAttributes(f) & FileSystem.BA_EXISTS) != 0); 2006 2007 if (!fs.createFileExclusively(f.getPath())) 2008 throw new IOException("Unable to create temporary file"); 2009 2010 return f; 2011 } 2012 2013 /** 2014 * Creates an empty file in the default temporary-file directory, using 2015 * the given prefix and suffix to generate its name. Invoking this method 2016 * is equivalent to invoking <code>{@link #createTempFile(java.lang.String, 2017 * java.lang.String, java.io.File) 2018 * createTempFile(prefix, suffix, null)}</code>. 2019 * 2020 * <p> The {@link 2021 * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[]) 2022 * Files.createTempFile} method provides an alternative method to create an 2023 * empty file in the temporary-file directory. Files created by that method 2024 * may have more restrictive access permissions to files created by this 2025 * method and so may be more suited to security-sensitive applications. 2026 * 2027 * @param prefix The prefix string to be used in generating the file's 2028 * name; must be at least three characters long 2029 * 2030 * @param suffix The suffix string to be used in generating the file's 2031 * name; may be <code>null</code>, in which case the 2032 * suffix <code>".tmp"</code> will be used 2033 * 2034 * @return An abstract pathname denoting a newly-created empty file 2035 * 2036 * @throws IllegalArgumentException 2037 * If the <code>prefix</code> argument contains fewer than three 2038 * characters 2039 * 2040 * @throws IOException If a file could not be created 2041 * 2042 * @throws SecurityException 2043 * If a security manager exists and its <code>{@link 2044 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code> 2045 * method does not allow a file to be created 2046 * 2047 * @since 1.2 2048 * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[]) 2049 */ createTempFile(String prefix, String suffix)2050 public static File createTempFile(String prefix, String suffix) 2051 throws IOException 2052 { 2053 return createTempFile(prefix, suffix, null); 2054 } 2055 2056 /* -- Basic infrastructure -- */ 2057 2058 /** 2059 * Compares two abstract pathnames lexicographically. The ordering 2060 * defined by this method depends upon the underlying system. On UNIX 2061 * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows 2062 * systems it is not. 2063 * 2064 * @param pathname The abstract pathname to be compared to this abstract 2065 * pathname 2066 * 2067 * @return Zero if the argument is equal to this abstract pathname, a 2068 * value less than zero if this abstract pathname is 2069 * lexicographically less than the argument, or a value greater 2070 * than zero if this abstract pathname is lexicographically 2071 * greater than the argument 2072 * 2073 * @since 1.2 2074 */ compareTo(File pathname)2075 public int compareTo(File pathname) { 2076 return fs.compare(this, pathname); 2077 } 2078 2079 /** 2080 * Tests this abstract pathname for equality with the given object. 2081 * Returns <code>true</code> if and only if the argument is not 2082 * <code>null</code> and is an abstract pathname that denotes the same file 2083 * or directory as this abstract pathname. Whether or not two abstract 2084 * pathnames are equal depends upon the underlying system. On UNIX 2085 * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows 2086 * systems it is not. 2087 * 2088 * @param obj The object to be compared with this abstract pathname 2089 * 2090 * @return <code>true</code> if and only if the objects are the same; 2091 * <code>false</code> otherwise 2092 */ equals(Object obj)2093 public boolean equals(Object obj) { 2094 if ((obj != null) && (obj instanceof File)) { 2095 return compareTo((File)obj) == 0; 2096 } 2097 return false; 2098 } 2099 2100 /** 2101 * Computes a hash code for this abstract pathname. Because equality of 2102 * abstract pathnames is inherently system-dependent, so is the computation 2103 * of their hash codes. On UNIX systems, the hash code of an abstract 2104 * pathname is equal to the exclusive <em>or</em> of the hash code 2105 * of its pathname string and the decimal value 2106 * <code>1234321</code>. On Microsoft Windows systems, the hash 2107 * code is equal to the exclusive <em>or</em> of the hash code of 2108 * its pathname string converted to lower case and the decimal 2109 * value <code>1234321</code>. Locale is not taken into account on 2110 * lowercasing the pathname string. 2111 * 2112 * @return A hash code for this abstract pathname 2113 */ hashCode()2114 public int hashCode() { 2115 return fs.hashCode(this); 2116 } 2117 2118 /** 2119 * Returns the pathname string of this abstract pathname. This is just the 2120 * string returned by the <code>{@link #getPath}</code> method. 2121 * 2122 * @return The string form of this abstract pathname 2123 */ toString()2124 public String toString() { 2125 return getPath(); 2126 } 2127 2128 /** 2129 * WriteObject is called to save this filename. 2130 * The separator character is saved also so it can be replaced 2131 * in case the path is reconstituted on a different host type. 2132 * <p> 2133 * @serialData Default fields followed by separator character. 2134 */ writeObject(java.io.ObjectOutputStream s)2135 private synchronized void writeObject(java.io.ObjectOutputStream s) 2136 throws IOException 2137 { 2138 s.defaultWriteObject(); 2139 s.writeChar(separatorChar); // Add the separator character 2140 } 2141 2142 /** 2143 * readObject is called to restore this filename. 2144 * The original separator character is read. If it is different 2145 * than the separator character on this system, then the old separator 2146 * is replaced by the local separator. 2147 */ readObject(java.io.ObjectInputStream s)2148 private synchronized void readObject(java.io.ObjectInputStream s) 2149 throws IOException, ClassNotFoundException 2150 { 2151 ObjectInputStream.GetField fields = s.readFields(); 2152 String pathField = (String)fields.get("path", null); 2153 char sep = s.readChar(); // read the previous separator char 2154 if (sep != separatorChar) 2155 pathField = pathField.replace(sep, separatorChar); 2156 String path = fs.normalize(pathField); 2157 UNSAFE.putObject(this, PATH_OFFSET, path); 2158 UNSAFE.putIntVolatile(this, PREFIX_LENGTH_OFFSET, fs.prefixLength(path)); 2159 } 2160 2161 private static final long PATH_OFFSET; 2162 private static final long PREFIX_LENGTH_OFFSET; 2163 private static final sun.misc.Unsafe UNSAFE; 2164 static { 2165 try { 2166 sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe(); 2167 PATH_OFFSET = unsafe.objectFieldOffset( 2168 File.class.getDeclaredField("path")); 2169 PREFIX_LENGTH_OFFSET = unsafe.objectFieldOffset( 2170 File.class.getDeclaredField("prefixLength")); 2171 UNSAFE = unsafe; 2172 } catch (ReflectiveOperationException e) { 2173 throw new Error(e); 2174 } 2175 } 2176 2177 2178 /** use serialVersionUID from JDK 1.0.2 for interoperability */ 2179 private static final long serialVersionUID = 301077366599181567L; 2180 2181 // -- Integration with java.nio.file -- 2182 2183 private volatile transient Path filePath; 2184 2185 /** 2186 * Returns a {@link Path java.nio.file.Path} object constructed from the 2187 * this abstract path. The resulting {@code Path} is associated with the 2188 * {@link java.nio.file.FileSystems#getDefault default-filesystem}. 2189 * 2190 * <p> The first invocation of this method works as if invoking it were 2191 * equivalent to evaluating the expression: 2192 * <blockquote><pre> 2193 * {@link java.nio.file.FileSystems#getDefault FileSystems.getDefault}().{@link 2194 * java.nio.file.FileSystem#getPath getPath}(this.{@link #getPath getPath}()); 2195 * </pre></blockquote> 2196 * Subsequent invocations of this method return the same {@code Path}. 2197 * 2198 * <p> If this abstract pathname is the empty abstract pathname then this 2199 * method returns a {@code Path} that may be used to access the current 2200 * user directory. 2201 * 2202 * @return a {@code Path} constructed from this abstract path 2203 * 2204 * @throws java.nio.file.InvalidPathException 2205 * if a {@code Path} object cannot be constructed from the abstract 2206 * path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath}) 2207 * 2208 * @since 1.7 2209 * @see Path#toFile 2210 */ toPath()2211 public Path toPath() { 2212 Path result = filePath; 2213 if (result == null) { 2214 synchronized (this) { 2215 result = filePath; 2216 if (result == null) { 2217 result = FileSystems.getDefault().getPath(path); 2218 filePath = result; 2219 } 2220 } 2221 } 2222 return result; 2223 } 2224 } 2225