jdk/src/share/classes/java/io/File.java
changeset 2057 3acf8e5e2ca0
parent 715 f16baef3a20e
child 2277 445a331b4a8b
equal deleted inserted replaced
2056:115e09b7a004 2057:3acf8e5e2ca0
     1 /*
     1 /*
     2  * Copyright 1994-2008 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 1994-2009 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     7  * published by the Free Software Foundation.  Sun designates this
    28 import java.beans.ConstructorProperties;
    28 import java.beans.ConstructorProperties;
    29 import java.net.URI;
    29 import java.net.URI;
    30 import java.net.URL;
    30 import java.net.URL;
    31 import java.net.MalformedURLException;
    31 import java.net.MalformedURLException;
    32 import java.net.URISyntaxException;
    32 import java.net.URISyntaxException;
    33 import java.util.ArrayList;
    33 import java.util.*;
    34 import java.util.Map;
    34 import java.nio.file.*;
    35 import java.util.Hashtable;
    35 import java.nio.file.attribute.*;
    36 import java.util.Random;
       
    37 import java.security.AccessController;
    36 import java.security.AccessController;
    38 import java.security.AccessControlException;
    37 import java.security.PrivilegedAction;
       
    38 import java.security.SecureRandom;
    39 import sun.security.action.GetPropertyAction;
    39 import sun.security.action.GetPropertyAction;
    40 
    40 
    41 
    41 
    42 /**
    42 /**
    43  * An abstract representation of file and directory pathnames.
    43  * An abstract representation of file and directory pathnames.
   129  *
   129  *
   130  * <p> Instances of the <code>File</code> class are immutable; that is, once
   130  * <p> Instances of the <code>File</code> class are immutable; that is, once
   131  * created, the abstract pathname represented by a <code>File</code> object
   131  * created, the abstract pathname represented by a <code>File</code> object
   132  * will never change.
   132  * will never change.
   133  *
   133  *
       
   134  * <h4>Interoperability with {@code java.nio.file} package</h4>
       
   135  *
       
   136  * <p> The <a href="../../java/nio/file/package-summary.html">{@code java.nio.file}</a>
       
   137  * package defines interfaces and classes for the Java virtual machine to access
       
   138  * files, file attributes, and file systems. This API may be used to overcome
       
   139  * many of the limitations of the {@code java.io.File} class.
       
   140  * The {@link #toPath toPath} method may be used to obtain a {@link
       
   141  * Path} that uses the abstract path represented by a {@code File} object to
       
   142  * locate a file. The resulting {@code Path} provides more efficient and
       
   143  * extensive access to file attributes, additional file operations, and I/O
       
   144  * exceptions to help diagnose errors when an operation on a file fails.
       
   145  *
   134  * @author  unascribed
   146  * @author  unascribed
   135  * @since   JDK1.0
   147  * @since   JDK1.0
   136  */
   148  */
   137 
   149 
   138 public class File
   150 public class File
   571      *          if a security manager exists and its <code>{@link
   583      *          if a security manager exists and its <code>{@link
   572      *          java.lang.SecurityManager#checkRead}</code> method denies
   584      *          java.lang.SecurityManager#checkRead}</code> method denies
   573      *          read access to the file
   585      *          read access to the file
   574      *
   586      *
   575      * @since   JDK1.1
   587      * @since   JDK1.1
       
   588      * @see     Path#toRealPath
   576      */
   589      */
   577     public String getCanonicalPath() throws IOException {
   590     public String getCanonicalPath() throws IOException {
   578         return fs.canonicalize(fs.resolve(this));
   591         return fs.canonicalize(fs.resolve(this));
   579     }
   592     }
   580 
   593 
   595      *          if a security manager exists and its <code>{@link
   608      *          if a security manager exists and its <code>{@link
   596      *          java.lang.SecurityManager#checkRead}</code> method denies
   609      *          java.lang.SecurityManager#checkRead}</code> method denies
   597      *          read access to the file
   610      *          read access to the file
   598      *
   611      *
   599      * @since 1.2
   612      * @since 1.2
       
   613      * @see     Path#toRealPath
   600      */
   614      */
   601     public File getCanonicalFile() throws IOException {
   615     public File getCanonicalFile() throws IOException {
   602         String canonPath = getCanonicalPath();
   616         String canonPath = getCanonicalPath();
   603         return new File(canonPath, fs.prefixLength(canonPath));
   617         return new File(canonPath, fs.prefixLength(canonPath));
   604     }
   618     }
   661      * pathnames, however, this relationship typically does not hold when a
   675      * pathnames, however, this relationship typically does not hold when a
   662      * <tt>file:</tt> URI that is created in a virtual machine on one operating
   676      * <tt>file:</tt> URI that is created in a virtual machine on one operating
   663      * system is converted into an abstract pathname in a virtual machine on a
   677      * system is converted into an abstract pathname in a virtual machine on a
   664      * different operating system.
   678      * different operating system.
   665      *
   679      *
       
   680      * <p> Note that when this abstract pathname represents a UNC pathname then
       
   681      * all components of the UNC (including the server name component) are encoded
       
   682      * in the {@code URI} path. The authority component is undefined, meaning
       
   683      * that it is represented as {@code null}. The {@link Path} class defines the
       
   684      * {@link Path#toUri toUri} method to encode the server name in the authority
       
   685      * component of the resulting {@code URI}. The {@link #toPath toPath} method
       
   686      * may be used to obtain a {@code Path} representing this abstract pathname.
       
   687      *
   666      * @return  An absolute, hierarchical URI with a scheme equal to
   688      * @return  An absolute, hierarchical URI with a scheme equal to
   667      *          <tt>"file"</tt>, a path representing this abstract pathname,
   689      *          <tt>"file"</tt>, a path representing this abstract pathname,
   668      *          and undefined authority, query, and fragment components
   690      *          and undefined authority, query, and fragment components
   669      * @throws SecurityException If a required system property value cannot
   691      * @throws SecurityException If a required system property value cannot
   670      * be accessed.
   692      * be accessed.
   762      *
   784      *
   763      * @throws  SecurityException
   785      * @throws  SecurityException
   764      *          If a security manager exists and its <code>{@link
   786      *          If a security manager exists and its <code>{@link
   765      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   787      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   766      *          method denies read access to the file
   788      *          method denies read access to the file
       
   789      *
       
   790      * @see Attributes#readBasicFileAttributes
   767      */
   791      */
   768     public boolean isDirectory() {
   792     public boolean isDirectory() {
   769         SecurityManager security = System.getSecurityManager();
   793         SecurityManager security = System.getSecurityManager();
   770         if (security != null) {
   794         if (security != null) {
   771             security.checkRead(path);
   795             security.checkRead(path);
   786      *
   810      *
   787      * @throws  SecurityException
   811      * @throws  SecurityException
   788      *          If a security manager exists and its <code>{@link
   812      *          If a security manager exists and its <code>{@link
   789      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   813      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   790      *          method denies read access to the file
   814      *          method denies read access to the file
       
   815      *
       
   816      * @see Attributes#readBasicFileAttributes
   791      */
   817      */
   792     public boolean isFile() {
   818     public boolean isFile() {
   793         SecurityManager security = System.getSecurityManager();
   819         SecurityManager security = System.getSecurityManager();
   794         if (security != null) {
   820         if (security != null) {
   795             security.checkRead(path);
   821             security.checkRead(path);
   834      *
   860      *
   835      * @throws  SecurityException
   861      * @throws  SecurityException
   836      *          If a security manager exists and its <code>{@link
   862      *          If a security manager exists and its <code>{@link
   837      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   863      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   838      *          method denies read access to the file
   864      *          method denies read access to the file
       
   865      *
       
   866      * @see Attributes#readBasicFileAttributes
   839      */
   867      */
   840     public long lastModified() {
   868     public long lastModified() {
   841         SecurityManager security = System.getSecurityManager();
   869         SecurityManager security = System.getSecurityManager();
   842         if (security != null) {
   870         if (security != null) {
   843             security.checkRead(path);
   871             security.checkRead(path);
   856      *
   884      *
   857      * @throws  SecurityException
   885      * @throws  SecurityException
   858      *          If a security manager exists and its <code>{@link
   886      *          If a security manager exists and its <code>{@link
   859      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   887      *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   860      *          method denies read access to the file
   888      *          method denies read access to the file
       
   889      *
       
   890      * @see Attributes#readBasicFileAttributes
   861      */
   891      */
   862     public long length() {
   892     public long length() {
   863         SecurityManager security = System.getSecurityManager();
   893         SecurityManager security = System.getSecurityManager();
   864         if (security != null) {
   894         if (security != null) {
   865             security.checkRead(path);
   895             security.checkRead(path);
   905     /**
   935     /**
   906      * Deletes the file or directory denoted by this abstract pathname.  If
   936      * Deletes the file or directory denoted by this abstract pathname.  If
   907      * this pathname denotes a directory, then the directory must be empty in
   937      * this pathname denotes a directory, then the directory must be empty in
   908      * order to be deleted.
   938      * order to be deleted.
   909      *
   939      *
       
   940      * <p> Note that the {@link Path} class defines the {@link Path#delete
       
   941      * delete} method to throw an {@link IOException} when a file cannot be
       
   942      * deleted. This is useful for error reporting and to diagnose why a file
       
   943      * cannot be deleted. The {@link #toPath toPath} method may be used to
       
   944      * obtain a {@code Path} representing this abstract pathname.
       
   945      *
   910      * @return  <code>true</code> if and only if the file or directory is
   946      * @return  <code>true</code> if and only if the file or directory is
   911      *          successfully deleted; <code>false</code> otherwise
   947      *          successfully deleted; <code>false</code> otherwise
   912      *
   948      *
   913      * @throws  SecurityException
   949      * @throws  SecurityException
   914      *          If a security manager exists and its <code>{@link
   950      *          If a security manager exists and its <code>{@link
   970      * complete path.
  1006      * complete path.
   971      *
  1007      *
   972      * <p> There is no guarantee that the name strings in the resulting array
  1008      * <p> There is no guarantee that the name strings in the resulting array
   973      * will appear in any specific order; they are not, in particular,
  1009      * will appear in any specific order; they are not, in particular,
   974      * guaranteed to appear in alphabetical order.
  1010      * guaranteed to appear in alphabetical order.
       
  1011      *
       
  1012      * <p> Note that the {@link Path} class defines the {@link
       
  1013      * Path#newDirectoryStream newDirectoryStream} method to open a directory
       
  1014      * and iterate over the names of the files in the directory. This may use
       
  1015      * less resources when working with very large directories. The {@link
       
  1016      * #toPath toPath} method may be used to obtain a {@code Path} representing
       
  1017      * this abstract pathname.
   975      *
  1018      *
   976      * @return  An array of strings naming the files and directories in the
  1019      * @return  An array of strings naming the files and directories in the
   977      *          directory denoted by this abstract pathname.  The array will be
  1020      *          directory denoted by this abstract pathname.  The array will be
   978      *          empty if the directory is empty.  Returns {@code null} if
  1021      *          empty if the directory is empty.  Returns {@code null} if
   979      *          this abstract pathname does not denote a directory, or if an
  1022      *          this abstract pathname does not denote a directory, or if an
  1022     public String[] list(FilenameFilter filter) {
  1065     public String[] list(FilenameFilter filter) {
  1023         String names[] = list();
  1066         String names[] = list();
  1024         if ((names == null) || (filter == null)) {
  1067         if ((names == null) || (filter == null)) {
  1025             return names;
  1068             return names;
  1026         }
  1069         }
  1027         ArrayList v = new ArrayList();
  1070         List<String> v = new ArrayList<String>();
  1028         for (int i = 0 ; i < names.length ; i++) {
  1071         for (int i = 0 ; i < names.length ; i++) {
  1029             if (filter.accept(this, names[i])) {
  1072             if (filter.accept(this, names[i])) {
  1030                 v.add(names[i]);
  1073                 v.add(names[i]);
  1031             }
  1074             }
  1032         }
  1075         }
  1033         return (String[])(v.toArray(new String[v.size()]));
  1076         return v.toArray(new String[v.size()]);
  1034     }
  1077     }
  1035 
  1078 
  1036     /**
  1079     /**
  1037      * Returns an array of abstract pathnames denoting the files in the
  1080      * Returns an array of abstract pathnames denoting the files in the
  1038      * directory denoted by this abstract pathname.
  1081      * directory denoted by this abstract pathname.
  1049      * the same directory.
  1092      * the same directory.
  1050      *
  1093      *
  1051      * <p> There is no guarantee that the name strings in the resulting array
  1094      * <p> There is no guarantee that the name strings in the resulting array
  1052      * will appear in any specific order; they are not, in particular,
  1095      * will appear in any specific order; they are not, in particular,
  1053      * guaranteed to appear in alphabetical order.
  1096      * guaranteed to appear in alphabetical order.
       
  1097      *
       
  1098      * <p> Note that the {@link Path} class defines the {@link
       
  1099      * Path#newDirectoryStream newDirectoryStream} method to open a directory
       
  1100      * and iterate over the names of the files in the directory. This may use
       
  1101      * less resources when working with very large directories. The {@link
       
  1102      * #toPath toPath} method may be used to obtain a {@code Path} representing
       
  1103      * this abstract pathname.
  1054      *
  1104      *
  1055      * @return  An array of abstract pathnames denoting the files and
  1105      * @return  An array of abstract pathnames denoting the files and
  1056      *          directories in the directory denoted by this abstract pathname.
  1106      *          directories in the directory denoted by this abstract pathname.
  1057      *          The array will be empty if the directory is empty.  Returns
  1107      *          The array will be empty if the directory is empty.  Returns
  1058      *          {@code null} if this abstract pathname does not denote a
  1108      *          {@code null} if this abstract pathname does not denote a
  1155     }
  1205     }
  1156 
  1206 
  1157     /**
  1207     /**
  1158      * Creates the directory named by this abstract pathname.
  1208      * Creates the directory named by this abstract pathname.
  1159      *
  1209      *
       
  1210      * <p> Note that the {@link Path} class defines the {@link Path#createDirectory
       
  1211      * createDirectory} method to throw an {@link IOException} when a directory
       
  1212      * cannot be created. This is useful for error reporting and to diagnose why
       
  1213      * a directory cannot be created. The {@link #toPath toPath} method may be
       
  1214      * used to obtain a {@code Path} representing this abstract pathname.
       
  1215      *
  1160      * @return  <code>true</code> if and only if the directory was
  1216      * @return  <code>true</code> if and only if the directory was
  1161      *          created; <code>false</code> otherwise
  1217      *          created; <code>false</code> otherwise
  1162      *
  1218      *
  1163      * @throws  SecurityException
  1219      * @throws  SecurityException
  1164      *          If a security manager exists and its <code>{@link
  1220      *          If a security manager exists and its <code>{@link
  1220      * file from one filesystem to another, it might not be atomic, and it
  1276      * file from one filesystem to another, it might not be atomic, and it
  1221      * might not succeed if a file with the destination abstract pathname
  1277      * might not succeed if a file with the destination abstract pathname
  1222      * already exists.  The return value should always be checked to make sure
  1278      * already exists.  The return value should always be checked to make sure
  1223      * that the rename operation was successful.
  1279      * that the rename operation was successful.
  1224      *
  1280      *
       
  1281      * <p> Note that the {@link Path} class defines the {@link Path#moveTo
       
  1282      * moveTo} method to move or rename a file in a platform independent manner.
       
  1283      * The {@link #toPath toPath} method may be used to obtain a {@code Path}
       
  1284      * representing this abstract pathname.
       
  1285      *
  1225      * @param  dest  The new abstract pathname for the named file
  1286      * @param  dest  The new abstract pathname for the named file
  1226      *
  1287      *
  1227      * @return  <code>true</code> if and only if the renaming succeeded;
  1288      * @return  <code>true</code> if and only if the renaming succeeded;
  1228      *          <code>false</code> otherwise
  1289      *          <code>false</code> otherwise
  1229      *
  1290      *
  1302             security.checkWrite(path);
  1363             security.checkWrite(path);
  1303         }
  1364         }
  1304         return fs.setReadOnly(this);
  1365         return fs.setReadOnly(this);
  1305     }
  1366     }
  1306 
  1367 
  1307    /**
  1368     /**
  1308      * Sets the owner's or everybody's write permission for this abstract
  1369      * Sets the owner's or everybody's write permission for this abstract
  1309      * pathname.
  1370      * pathname.
       
  1371      *
       
  1372      * <p> The {@link Attributes Attributes} class defines methods that operate
       
  1373      * on file attributes including file permissions. This may be used when
       
  1374      * finer manipulation of file permissions is required.
  1310      *
  1375      *
  1311      * @param   writable
  1376      * @param   writable
  1312      *          If <code>true</code>, sets the access permission to allow write
  1377      *          If <code>true</code>, sets the access permission to allow write
  1313      *          operations; if <code>false</code> to disallow write operations
  1378      *          operations; if <code>false</code> to disallow write operations
  1314      *
  1379      *
  1369 
  1434 
  1370     /**
  1435     /**
  1371      * Sets the owner's or everybody's read permission for this abstract
  1436      * Sets the owner's or everybody's read permission for this abstract
  1372      * pathname.
  1437      * pathname.
  1373      *
  1438      *
       
  1439      * <p> The {@link Attributes Attributes} class defines methods that operate
       
  1440      * on file attributes including file permissions. This may be used when
       
  1441      * finer manipulation of file permissions is required.
       
  1442      *
  1374      * @param   readable
  1443      * @param   readable
  1375      *          If <code>true</code>, sets the access permission to allow read
  1444      *          If <code>true</code>, sets the access permission to allow read
  1376      *          operations; if <code>false</code> to disallow read operations
  1445      *          operations; if <code>false</code> to disallow read operations
  1377      *
  1446      *
  1378      * @param   ownerOnly
  1447      * @param   ownerOnly
  1437     }
  1506     }
  1438 
  1507 
  1439     /**
  1508     /**
  1440      * Sets the owner's or everybody's execute permission for this abstract
  1509      * Sets the owner's or everybody's execute permission for this abstract
  1441      * pathname.
  1510      * pathname.
       
  1511      *
       
  1512      * <p> The {@link Attributes Attributes} class defines methods that operate
       
  1513      * on file attributes including file permissions. This may be used when
       
  1514      * finer manipulation of file permissions is required.
  1442      *
  1515      *
  1443      * @param   executable
  1516      * @param   executable
  1444      *          If <code>true</code>, sets the access permission to allow execute
  1517      *          If <code>true</code>, sets the access permission to allow execute
  1445      *          operations; if <code>false</code> to disallow execute operations
  1518      *          operations; if <code>false</code> to disallow execute operations
  1446      *
  1519      *
  1676     }
  1749     }
  1677 
  1750 
  1678 
  1751 
  1679     /* -- Temporary files -- */
  1752     /* -- Temporary files -- */
  1680 
  1753 
  1681     private static final Object tmpFileLock = new Object();
  1754     private static class TemporaryDirectory {
  1682 
  1755         private TemporaryDirectory() { }
  1683     private static int counter = -1; /* Protected by tmpFileLock */
  1756 
  1684 
  1757         static final String valueAsString = fs.normalize(
  1685     private static File generateFile(String prefix, String suffix, File dir)
  1758             AccessController.doPrivileged(new GetPropertyAction("java.io.tmpdir")));
  1686         throws IOException
  1759         static final File valueAsFile =
  1687     {
  1760             new File(valueAsString, fs.prefixLength(valueAsString));
  1688         if (counter == -1) {
  1761 
  1689             counter = new Random().nextInt() & 0xffff;
  1762         // file name generation
  1690         }
  1763         private static final SecureRandom random = new SecureRandom();
  1691         counter++;
  1764         static File generateFile(String prefix, String suffix, File dir) {
  1692         return new File(dir, prefix + Integer.toString(counter) + suffix);
  1765             long n = random.nextLong();
  1693     }
  1766             if (n == Long.MIN_VALUE) {
  1694 
  1767                 n = 0;      // corner case
  1695     private static String tmpdir; /* Protected by tmpFileLock */
  1768             } else {
  1696 
  1769                 n = Math.abs(n);
  1697     private static String getTempDir() {
       
  1698         if (tmpdir == null)
       
  1699             tmpdir = fs.normalize(
       
  1700                 AccessController.doPrivileged(
       
  1701                     new GetPropertyAction("java.io.tmpdir")));
       
  1702         return tmpdir;
       
  1703     }
       
  1704 
       
  1705     private static boolean checkAndCreate(String filename, SecurityManager sm)
       
  1706         throws IOException
       
  1707     {
       
  1708         if (sm != null) {
       
  1709             try {
       
  1710                 sm.checkWrite(filename);
       
  1711             } catch (AccessControlException x) {
       
  1712                 /* Throwing the original AccessControlException could disclose
       
  1713                    the location of the default temporary directory, so we
       
  1714                    re-throw a more innocuous SecurityException */
       
  1715                 throw new SecurityException("Unable to create temporary file");
       
  1716             }
  1770             }
  1717         }
  1771             return new File(dir, prefix + Long.toString(n) + suffix);
  1718         return fs.createFileExclusively(filename);
  1772         }
       
  1773 
       
  1774         // default file permissions
       
  1775         static final FileAttribute<Set<PosixFilePermission>> defaultPosixFilePermissions =
       
  1776             PosixFilePermissions.asFileAttribute(EnumSet
       
  1777                 .of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE));
       
  1778         static final boolean isPosix = isPosix();
       
  1779         static boolean isPosix() {
       
  1780             return AccessController.doPrivileged(
       
  1781                 new PrivilegedAction<Boolean>() {
       
  1782                     public Boolean run() {
       
  1783                         try {
       
  1784                             return FileSystems.getDefault().getPath(valueAsString)
       
  1785                                 .getFileStore().supportsFileAttributeView("posix");
       
  1786                         } catch (IOException e) {
       
  1787                             throw new IOError(e);
       
  1788                         }
       
  1789                     }
       
  1790                 });
       
  1791         }
  1719     }
  1792     }
  1720 
  1793 
  1721     /**
  1794     /**
  1722      * <p> Creates a new empty file in the specified directory, using the
  1795      * <p> Creates a new empty file in the specified directory, using the
  1723      * given prefix and suffix strings to generate its name.  If this method
  1796      * given prefix and suffix strings to generate its name.  If this method
  1789      */
  1862      */
  1790     public static File createTempFile(String prefix, String suffix,
  1863     public static File createTempFile(String prefix, String suffix,
  1791                                       File directory)
  1864                                       File directory)
  1792         throws IOException
  1865         throws IOException
  1793     {
  1866     {
  1794         if (prefix == null) throw new NullPointerException();
       
  1795         if (prefix.length() < 3)
  1867         if (prefix.length() < 3)
  1796             throw new IllegalArgumentException("Prefix string too short");
  1868             throw new IllegalArgumentException("Prefix string too short");
  1797         String s = (suffix == null) ? ".tmp" : suffix;
  1869         if (suffix == null)
  1798         synchronized (tmpFileLock) {
  1870             suffix = ".tmp";
  1799             if (directory == null) {
  1871 
  1800                 String tmpDir = getTempDir();
  1872         File tmpdir = (directory != null) ?
  1801                 directory = new File(tmpDir, fs.prefixLength(tmpDir));
  1873             directory : TemporaryDirectory.valueAsFile;
       
  1874         SecurityManager sm = System.getSecurityManager();
       
  1875         File f;
       
  1876         do {
       
  1877             f = TemporaryDirectory.generateFile(prefix, suffix, tmpdir);
       
  1878             if (sm != null) {
       
  1879                 try {
       
  1880                     sm.checkWrite(f.getPath());
       
  1881                 } catch (SecurityException se) {
       
  1882                     // don't reveal temporary directory location
       
  1883                     if (directory == null)
       
  1884                         throw new SecurityException("Unable to create temporary file");
       
  1885                     throw se;
       
  1886                 }
  1802             }
  1887             }
  1803             SecurityManager sm = System.getSecurityManager();
  1888         } while (!fs.createFileExclusively(f.getPath()));
  1804             File f;
  1889         return f;
  1805             do {
       
  1806                 f = generateFile(prefix, s, directory);
       
  1807             } while (!checkAndCreate(f.getPath(), sm));
       
  1808             return f;
       
  1809         }
       
  1810     }
  1890     }
  1811 
  1891 
  1812     /**
  1892     /**
  1813      * Creates an empty file in the default temporary-file directory, using
  1893      * Creates an empty file in the default temporary-file directory, using
  1814      * the given prefix and suffix to generate its name.  Invoking this method
  1894      * the given prefix and suffix to generate its name.  Invoking this method
  1842         throws IOException
  1922         throws IOException
  1843     {
  1923     {
  1844         return createTempFile(prefix, suffix, null);
  1924         return createTempFile(prefix, suffix, null);
  1845     }
  1925     }
  1846 
  1926 
       
  1927     /**
       
  1928      * Creates an empty file in the default temporary-file directory, using
       
  1929      * the given prefix and suffix to generate its name. This method is
       
  1930      * equivalent to invoking the {@link #createTempFile(String,String)
       
  1931      * createTempFile(prefix,&nbsp;suffix)} method with the addition that the
       
  1932      * resulting pathname may be requested to be deleted when the Java virtual
       
  1933      * machine terminates, and the initial file attributes to set atomically
       
  1934      * when creating the file may be specified.
       
  1935      *
       
  1936      * <p> When the value of the {@code deleteOnExit} method is {@code true}
       
  1937      * then the resulting file is requested to be deleted when the Java virtual
       
  1938      * machine terminates as if by invoking the {@link #deleteOnExit deleteOnExit}
       
  1939      * method.
       
  1940      *
       
  1941      * <p> The {@code attrs} parameter is an optional array of {@link FileAttribute
       
  1942      * attributes} to set atomically when creating the file. Each attribute is
       
  1943      * identified by its {@link FileAttribute#name name}. If more than one attribute
       
  1944      * of the same name is included in the array then all but the last occurrence
       
  1945      * is ignored.
       
  1946      *
       
  1947      * @param   prefix
       
  1948      *          The prefix string to be used in generating the file's
       
  1949      *          name; must be at least three characters long
       
  1950      * @param   suffix
       
  1951      *          The suffix string to be used in generating the file's
       
  1952      *          name; may be {@code null}, in which case the suffix
       
  1953      *          {@code ".tmp"} will be used
       
  1954      * @param   deleteOnExit
       
  1955      *          {@code true} if the file denoted by resulting pathname be
       
  1956      *          deleted when the Java virtual machine terminates
       
  1957      * @param   attrs
       
  1958      *          An optional list of file attributes to set atomically when creating
       
  1959      *          the file
       
  1960      *
       
  1961      * @return  An abstract pathname denoting a newly-created empty file
       
  1962      *
       
  1963      * @throws  IllegalArgumentException
       
  1964      *          If the <code>prefix</code> argument contains fewer than three
       
  1965      *          characters
       
  1966      * @throws  UnsupportedOperationException
       
  1967      *          If the array contains an attribute that cannot be set atomically
       
  1968      *          when creating the file
       
  1969      * @throws  IOException
       
  1970      *          If a file could not be created
       
  1971      * @throws  SecurityException
       
  1972      *          If a security manager exists and its <code>{@link
       
  1973      *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
       
  1974      *          method does not allow a file to be created. When the {@code
       
  1975      *          deleteOnExit} parameter has the value {@code true} then the
       
  1976      *          security manager's {@link
       
  1977      *          java.lang.SecurityManager#checkDelete(java.lang.String)} is
       
  1978      *          invoked to check delete access to the file.
       
  1979      * @since 1.7
       
  1980      */
       
  1981     public static File createTempFile(String prefix,
       
  1982                                       String suffix,
       
  1983                                       boolean deleteOnExit,
       
  1984                                       FileAttribute<?>... attrs)
       
  1985         throws IOException
       
  1986     {
       
  1987         if (prefix.length() < 3)
       
  1988             throw new IllegalArgumentException("Prefix string too short");
       
  1989         suffix = (suffix == null) ? ".tmp" : suffix;
       
  1990 
       
  1991         // special case POSIX environments so that 0600 is used as the file mode
       
  1992         if (TemporaryDirectory.isPosix) {
       
  1993             if (attrs.length == 0) {
       
  1994                 // no attributes so use default permissions
       
  1995                 attrs = new FileAttribute<?>[1];
       
  1996                 attrs[0] = TemporaryDirectory.defaultPosixFilePermissions;
       
  1997             } else {
       
  1998                 // check if posix permissions given; if not use default
       
  1999                 boolean hasPermissions = false;
       
  2000                 for (int i=0; i<attrs.length; i++) {
       
  2001                     if (attrs[i].name().equals("posix:permissions")) {
       
  2002                         hasPermissions = true;
       
  2003                         break;
       
  2004                     }
       
  2005                 }
       
  2006                 if (!hasPermissions) {
       
  2007                     FileAttribute<?>[] copy = new FileAttribute<?>[attrs.length+1];
       
  2008                     System.arraycopy(attrs, 0, copy, 0, attrs.length);
       
  2009                     attrs = copy;
       
  2010                     attrs[attrs.length-1] =
       
  2011                         TemporaryDirectory.defaultPosixFilePermissions;
       
  2012                 }
       
  2013             }
       
  2014         }
       
  2015 
       
  2016         // use Path#createFile to create file
       
  2017         SecurityManager sm = System.getSecurityManager();
       
  2018         for (;;) {
       
  2019             File f = TemporaryDirectory
       
  2020                 .generateFile(prefix, suffix, TemporaryDirectory.valueAsFile);
       
  2021             if (sm != null && deleteOnExit)
       
  2022                 sm.checkDelete(f.getPath());
       
  2023             try {
       
  2024                 f.toPath().createFile(attrs);
       
  2025                 if (deleteOnExit)
       
  2026                     DeleteOnExitHook.add(f.getPath());
       
  2027                 return f;
       
  2028             } catch (InvalidPathException e) {
       
  2029                 // don't reveal temporary directory location
       
  2030                 if (sm != null)
       
  2031                     throw new IllegalArgumentException("Invalid prefix or suffix");
       
  2032                 throw e;
       
  2033             } catch (SecurityException e) {
       
  2034                 // don't reveal temporary directory location
       
  2035                 if (sm != null)
       
  2036                     throw new SecurityException("Unable to create temporary file");
       
  2037                 throw e;
       
  2038             } catch (FileAlreadyExistsException e) {
       
  2039                 // ignore
       
  2040             }
       
  2041         }
       
  2042     }
  1847 
  2043 
  1848     /* -- Basic infrastructure -- */
  2044     /* -- Basic infrastructure -- */
  1849 
  2045 
  1850     /**
  2046     /**
  1851      * Compares two abstract pathnames lexicographically.  The ordering
  2047      * Compares two abstract pathnames lexicographically.  The ordering
  1961                 }
  2157                 }
  1962             }
  2158             }
  1963         );
  2159         );
  1964     }
  2160     }
  1965 
  2161 
  1966 
  2162     // -- Integration with java.nio.file --
       
  2163 
       
  2164     private volatile transient Path filePath;
       
  2165 
       
  2166     /**
       
  2167      * Returns a {@link Path java.nio.file.Path} object constructed from the
       
  2168      * this abstract path. The first invocation of this method works as if
       
  2169      * invoking it were equivalent to evaluating the expression:
       
  2170      * <blockquote><pre>
       
  2171      * {@link FileSystems#getDefault FileSystems.getDefault}().{@link FileSystem#getPath getPath}(this.{@link #getPath getPath}());
       
  2172      * </pre></blockquote>
       
  2173      * Subsequent invocations of this method return the same {@code Path}.
       
  2174      *
       
  2175      * <p> If this abstract pathname is the empty abstract pathname then this
       
  2176      * method returns a {@code Path} that may be used to access to the current
       
  2177      * user directory.
       
  2178      *
       
  2179      * @return  A {@code Path} constructed from this abstract path. The resulting
       
  2180      *          {@code Path} is associated with the {@link FileSystems#getDefault
       
  2181      *          default-filesystem}.
       
  2182      *
       
  2183      * @throws  InvalidPathException
       
  2184      *          If a {@code Path} object cannot be constructed from the abstract
       
  2185      *          path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
       
  2186      *
       
  2187      * @since   1.7
       
  2188      */
       
  2189     public Path toPath() {
       
  2190         if (filePath == null) {
       
  2191             synchronized (this) {
       
  2192                 if (filePath == null) {
       
  2193                     if (path.length() == 0) {
       
  2194                         // assume default file system treats "." as current directory
       
  2195                         filePath = Paths.get(".");
       
  2196                     } else {
       
  2197                         filePath = Paths.get(path);
       
  2198                     }
       
  2199                 }
       
  2200             }
       
  2201         }
       
  2202         return filePath;
       
  2203     }
  1967 }
  2204 }