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