jdk/src/share/classes/java/io/File.java
changeset 17430 c445531b8f6b
parent 14324 3510b4bf90ee
child 18157 ee3bda8e26c6
equal deleted inserted replaced
17429:56bf7cddf22f 17430:c445531b8f6b
     1 /*
     1 /*
     2  * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1994, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
   154      * The FileSystem object representing the platform's local file system.
   154      * The FileSystem object representing the platform's local file system.
   155      */
   155      */
   156     private static final FileSystem fs = DefaultFileSystem.getFileSystem();
   156     private static final FileSystem fs = DefaultFileSystem.getFileSystem();
   157 
   157 
   158     /**
   158     /**
   159      * This abstract pathname's normalized pathname string.  A normalized
   159      * This abstract pathname's normalized pathname string. A normalized
   160      * pathname string uses the default name-separator character and does not
   160      * pathname string uses the default name-separator character and does not
   161      * contain any duplicate or redundant separators.
   161      * contain any duplicate or redundant separators.
   162      *
   162      *
   163      * @serial
   163      * @serial
   164      */
   164      */
   165     private final String path;
   165     private final String path;
       
   166 
       
   167     /**
       
   168      * Enum type that indicates the status of a file path.
       
   169      */
       
   170     private static enum PathStatus { INVALID, CHECKED };
       
   171 
       
   172     /**
       
   173      * The flag indicating whether the file path is invalid.
       
   174      */
       
   175     private transient PathStatus status = null;
       
   176 
       
   177     /**
       
   178      * Check if the file has an invalid path. Currently, the inspection of
       
   179      * a file path is very limited, and it only covers Nul character check.
       
   180      * Returning true means the path is definitely invalid/garbage. But
       
   181      * returning false does not guarantee that the path is valid.
       
   182      *
       
   183      * @return true if the file path is invalid.
       
   184      */
       
   185     final boolean isInvalid() {
       
   186         if (status == null) {
       
   187             status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
       
   188                                                        : PathStatus.INVALID;
       
   189         }
       
   190         return status == PathStatus.INVALID;
       
   191     }
   166 
   192 
   167     /**
   193     /**
   168      * The length of this abstract pathname's prefix, or zero if it has no
   194      * The length of this abstract pathname's prefix, or zero if it has no
   169      * prefix.
   195      * prefix.
   170      */
   196      */
   584      *
   610      *
   585      * @since   JDK1.1
   611      * @since   JDK1.1
   586      * @see     Path#toRealPath
   612      * @see     Path#toRealPath
   587      */
   613      */
   588     public String getCanonicalPath() throws IOException {
   614     public String getCanonicalPath() throws IOException {
       
   615         if (isInvalid()) {
       
   616             throw new IOException("Invalid file path");
       
   617         }
   589         return fs.canonicalize(fs.resolve(this));
   618         return fs.canonicalize(fs.resolve(this));
   590     }
   619     }
   591 
   620 
   592     /**
   621     /**
   593      * Returns the canonical form of this abstract pathname.  Equivalent to
   622      * Returns the canonical form of this abstract pathname.  Equivalent to
   649      * {@link #toURI() toURI} method, and then converting the URI into a URL
   678      * {@link #toURI() toURI} method, and then converting the URI into a URL
   650      * via the {@link java.net.URI#toURL() URI.toURL} method.
   679      * via the {@link java.net.URI#toURL() URI.toURL} method.
   651      */
   680      */
   652     @Deprecated
   681     @Deprecated
   653     public URL toURL() throws MalformedURLException {
   682     public URL toURL() throws MalformedURLException {
       
   683         if (isInvalid()) {
       
   684             throw new MalformedURLException("Invalid file path");
       
   685         }
   654         return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
   686         return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
   655     }
   687     }
   656 
   688 
   657     /**
   689     /**
   658      * Constructs a <tt>file:</tt> URI that represents this abstract pathname.
   690      * Constructs a <tt>file:</tt> URI that represents this abstract pathname.
   728     public boolean canRead() {
   760     public boolean canRead() {
   729         SecurityManager security = System.getSecurityManager();
   761         SecurityManager security = System.getSecurityManager();
   730         if (security != null) {
   762         if (security != null) {
   731             security.checkRead(path);
   763             security.checkRead(path);
   732         }
   764         }
       
   765         if (isInvalid()) {
       
   766             return false;
       
   767         }
   733         return fs.checkAccess(this, FileSystem.ACCESS_READ);
   768         return fs.checkAccess(this, FileSystem.ACCESS_READ);
   734     }
   769     }
   735 
   770 
   736     /**
   771     /**
   737      * Tests whether the application can modify the file denoted by this
   772      * Tests whether the application can modify the file denoted by this
   753     public boolean canWrite() {
   788     public boolean canWrite() {
   754         SecurityManager security = System.getSecurityManager();
   789         SecurityManager security = System.getSecurityManager();
   755         if (security != null) {
   790         if (security != null) {
   756             security.checkWrite(path);
   791             security.checkWrite(path);
   757         }
   792         }
       
   793         if (isInvalid()) {
       
   794             return false;
       
   795         }
   758         return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
   796         return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
   759     }
   797     }
   760 
   798 
   761     /**
   799     /**
   762      * Tests whether the file or directory denoted by this abstract pathname
   800      * Tests whether the file or directory denoted by this abstract pathname
   772      */
   810      */
   773     public boolean exists() {
   811     public boolean exists() {
   774         SecurityManager security = System.getSecurityManager();
   812         SecurityManager security = System.getSecurityManager();
   775         if (security != null) {
   813         if (security != null) {
   776             security.checkRead(path);
   814             security.checkRead(path);
       
   815         }
       
   816         if (isInvalid()) {
       
   817             return false;
   777         }
   818         }
   778         return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
   819         return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
   779     }
   820     }
   780 
   821 
   781     /**
   822     /**
   800     public boolean isDirectory() {
   841     public boolean isDirectory() {
   801         SecurityManager security = System.getSecurityManager();
   842         SecurityManager security = System.getSecurityManager();
   802         if (security != null) {
   843         if (security != null) {
   803             security.checkRead(path);
   844             security.checkRead(path);
   804         }
   845         }
       
   846         if (isInvalid()) {
       
   847             return false;
       
   848         }
   805         return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
   849         return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
   806                 != 0);
   850                 != 0);
   807     }
   851     }
   808 
   852 
   809     /**
   853     /**
   830     public boolean isFile() {
   874     public boolean isFile() {
   831         SecurityManager security = System.getSecurityManager();
   875         SecurityManager security = System.getSecurityManager();
   832         if (security != null) {
   876         if (security != null) {
   833             security.checkRead(path);
   877             security.checkRead(path);
   834         }
   878         }
       
   879         if (isInvalid()) {
       
   880             return false;
       
   881         }
   835         return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
   882         return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
   836     }
   883     }
   837 
   884 
   838     /**
   885     /**
   839      * Tests whether the file named by this abstract pathname is a hidden
   886      * Tests whether the file named by this abstract pathname is a hidden
   855      */
   902      */
   856     public boolean isHidden() {
   903     public boolean isHidden() {
   857         SecurityManager security = System.getSecurityManager();
   904         SecurityManager security = System.getSecurityManager();
   858         if (security != null) {
   905         if (security != null) {
   859             security.checkRead(path);
   906             security.checkRead(path);
       
   907         }
       
   908         if (isInvalid()) {
       
   909             return false;
   860         }
   910         }
   861         return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
   911         return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
   862     }
   912     }
   863 
   913 
   864     /**
   914     /**
   885     public long lastModified() {
   935     public long lastModified() {
   886         SecurityManager security = System.getSecurityManager();
   936         SecurityManager security = System.getSecurityManager();
   887         if (security != null) {
   937         if (security != null) {
   888             security.checkRead(path);
   938             security.checkRead(path);
   889         }
   939         }
       
   940         if (isInvalid()) {
       
   941             return 0L;
       
   942         }
   890         return fs.getLastModifiedTime(this);
   943         return fs.getLastModifiedTime(this);
   891     }
   944     }
   892 
   945 
   893     /**
   946     /**
   894      * Returns the length of the file denoted by this abstract pathname.
   947      * Returns the length of the file denoted by this abstract pathname.
   912      */
   965      */
   913     public long length() {
   966     public long length() {
   914         SecurityManager security = System.getSecurityManager();
   967         SecurityManager security = System.getSecurityManager();
   915         if (security != null) {
   968         if (security != null) {
   916             security.checkRead(path);
   969             security.checkRead(path);
       
   970         }
       
   971         if (isInvalid()) {
       
   972             return 0L;
   917         }
   973         }
   918         return fs.getLength(this);
   974         return fs.getLength(this);
   919     }
   975     }
   920 
   976 
   921 
   977 
   948      * @since 1.2
  1004      * @since 1.2
   949      */
  1005      */
   950     public boolean createNewFile() throws IOException {
  1006     public boolean createNewFile() throws IOException {
   951         SecurityManager security = System.getSecurityManager();
  1007         SecurityManager security = System.getSecurityManager();
   952         if (security != null) security.checkWrite(path);
  1008         if (security != null) security.checkWrite(path);
       
  1009         if (isInvalid()) {
       
  1010             throw new IOException("Invalid file path");
       
  1011         }
   953         return fs.createFileExclusively(path);
  1012         return fs.createFileExclusively(path);
   954     }
  1013     }
   955 
  1014 
   956     /**
  1015     /**
   957      * Deletes the file or directory denoted by this abstract pathname.  If
  1016      * Deletes the file or directory denoted by this abstract pathname.  If
   973      */
  1032      */
   974     public boolean delete() {
  1033     public boolean delete() {
   975         SecurityManager security = System.getSecurityManager();
  1034         SecurityManager security = System.getSecurityManager();
   976         if (security != null) {
  1035         if (security != null) {
   977             security.checkDelete(path);
  1036             security.checkDelete(path);
       
  1037         }
       
  1038         if (isInvalid()) {
       
  1039             return false;
   978         }
  1040         }
   979         return fs.delete(this);
  1041         return fs.delete(this);
   980     }
  1042     }
   981 
  1043 
   982     /**
  1044     /**
  1009     public void deleteOnExit() {
  1071     public void deleteOnExit() {
  1010         SecurityManager security = System.getSecurityManager();
  1072         SecurityManager security = System.getSecurityManager();
  1011         if (security != null) {
  1073         if (security != null) {
  1012             security.checkDelete(path);
  1074             security.checkDelete(path);
  1013         }
  1075         }
       
  1076         if (isInvalid()) {
       
  1077             return;
       
  1078         }
  1014         DeleteOnExitHook.add(path);
  1079         DeleteOnExitHook.add(path);
  1015     }
  1080     }
  1016 
  1081 
  1017     /**
  1082     /**
  1018      * Returns an array of strings naming the files and directories in the
  1083      * Returns an array of strings naming the files and directories in the
  1048      */
  1113      */
  1049     public String[] list() {
  1114     public String[] list() {
  1050         SecurityManager security = System.getSecurityManager();
  1115         SecurityManager security = System.getSecurityManager();
  1051         if (security != null) {
  1116         if (security != null) {
  1052             security.checkRead(path);
  1117             security.checkRead(path);
       
  1118         }
       
  1119         if (isInvalid()) {
       
  1120             return null;
  1053         }
  1121         }
  1054         return fs.list(this);
  1122         return fs.list(this);
  1055     }
  1123     }
  1056 
  1124 
  1057     /**
  1125     /**
  1240     public boolean mkdir() {
  1308     public boolean mkdir() {
  1241         SecurityManager security = System.getSecurityManager();
  1309         SecurityManager security = System.getSecurityManager();
  1242         if (security != null) {
  1310         if (security != null) {
  1243             security.checkWrite(path);
  1311             security.checkWrite(path);
  1244         }
  1312         }
       
  1313         if (isInvalid()) {
       
  1314             return false;
       
  1315         }
  1245         return fs.createDirectory(this);
  1316         return fs.createDirectory(this);
  1246     }
  1317     }
  1247 
  1318 
  1248     /**
  1319     /**
  1249      * Creates the directory named by this abstract pathname, including any
  1320      * Creates the directory named by this abstract pathname, including any
  1315         SecurityManager security = System.getSecurityManager();
  1386         SecurityManager security = System.getSecurityManager();
  1316         if (security != null) {
  1387         if (security != null) {
  1317             security.checkWrite(path);
  1388             security.checkWrite(path);
  1318             security.checkWrite(dest.path);
  1389             security.checkWrite(dest.path);
  1319         }
  1390         }
       
  1391         if (dest == null) {
       
  1392             throw new NullPointerException();
       
  1393         }
       
  1394         if (this.isInvalid() || dest.isInvalid()) {
       
  1395             return false;
       
  1396         }
  1320         return fs.rename(this, dest);
  1397         return fs.rename(this, dest);
  1321     }
  1398     }
  1322 
  1399 
  1323     /**
  1400     /**
  1324      * Sets the last-modified time of the file or directory named by this
  1401      * Sets the last-modified time of the file or directory named by this
  1349     public boolean setLastModified(long time) {
  1426     public boolean setLastModified(long time) {
  1350         if (time < 0) throw new IllegalArgumentException("Negative time");
  1427         if (time < 0) throw new IllegalArgumentException("Negative time");
  1351         SecurityManager security = System.getSecurityManager();
  1428         SecurityManager security = System.getSecurityManager();
  1352         if (security != null) {
  1429         if (security != null) {
  1353             security.checkWrite(path);
  1430             security.checkWrite(path);
       
  1431         }
       
  1432         if (isInvalid()) {
       
  1433             return false;
  1354         }
  1434         }
  1355         return fs.setLastModifiedTime(this, time);
  1435         return fs.setLastModifiedTime(this, time);
  1356     }
  1436     }
  1357 
  1437 
  1358     /**
  1438     /**
  1377     public boolean setReadOnly() {
  1457     public boolean setReadOnly() {
  1378         SecurityManager security = System.getSecurityManager();
  1458         SecurityManager security = System.getSecurityManager();
  1379         if (security != null) {
  1459         if (security != null) {
  1380             security.checkWrite(path);
  1460             security.checkWrite(path);
  1381         }
  1461         }
       
  1462         if (isInvalid()) {
       
  1463             return false;
       
  1464         }
  1382         return fs.setReadOnly(this);
  1465         return fs.setReadOnly(this);
  1383     }
  1466     }
  1384 
  1467 
  1385     /**
  1468     /**
  1386      * Sets the owner's or everybody's write permission for this abstract
  1469      * Sets the owner's or everybody's write permission for this abstract
  1417     public boolean setWritable(boolean writable, boolean ownerOnly) {
  1500     public boolean setWritable(boolean writable, boolean ownerOnly) {
  1418         SecurityManager security = System.getSecurityManager();
  1501         SecurityManager security = System.getSecurityManager();
  1419         if (security != null) {
  1502         if (security != null) {
  1420             security.checkWrite(path);
  1503             security.checkWrite(path);
  1421         }
  1504         }
       
  1505         if (isInvalid()) {
       
  1506             return false;
       
  1507         }
  1422         return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
  1508         return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
  1423     }
  1509     }
  1424 
  1510 
  1425     /**
  1511     /**
  1426      * A convenience method to set the owner's write permission for this abstract
  1512      * A convenience method to set the owner's write permission for this abstract
  1491     public boolean setReadable(boolean readable, boolean ownerOnly) {
  1577     public boolean setReadable(boolean readable, boolean ownerOnly) {
  1492         SecurityManager security = System.getSecurityManager();
  1578         SecurityManager security = System.getSecurityManager();
  1493         if (security != null) {
  1579         if (security != null) {
  1494             security.checkWrite(path);
  1580             security.checkWrite(path);
  1495         }
  1581         }
       
  1582         if (isInvalid()) {
       
  1583             return false;
       
  1584         }
  1496         return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
  1585         return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
  1497     }
  1586     }
  1498 
  1587 
  1499     /**
  1588     /**
  1500      * A convenience method to set the owner's read permission for this abstract
  1589      * A convenience method to set the owner's read permission for this abstract
  1568     public boolean setExecutable(boolean executable, boolean ownerOnly) {
  1657     public boolean setExecutable(boolean executable, boolean ownerOnly) {
  1569         SecurityManager security = System.getSecurityManager();
  1658         SecurityManager security = System.getSecurityManager();
  1570         if (security != null) {
  1659         if (security != null) {
  1571             security.checkWrite(path);
  1660             security.checkWrite(path);
  1572         }
  1661         }
       
  1662         if (isInvalid()) {
       
  1663             return false;
       
  1664         }
  1573         return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
  1665         return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
  1574     }
  1666     }
  1575 
  1667 
  1576     /**
  1668     /**
  1577      * A convenience method to set the owner's execute permission for this
  1669      * A convenience method to set the owner's execute permission for this
  1626      */
  1718      */
  1627     public boolean canExecute() {
  1719     public boolean canExecute() {
  1628         SecurityManager security = System.getSecurityManager();
  1720         SecurityManager security = System.getSecurityManager();
  1629         if (security != null) {
  1721         if (security != null) {
  1630             security.checkExec(path);
  1722             security.checkExec(path);
       
  1723         }
       
  1724         if (isInvalid()) {
       
  1725             return false;
  1631         }
  1726         }
  1632         return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
  1727         return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
  1633     }
  1728     }
  1634 
  1729 
  1635 
  1730 
  1703         SecurityManager sm = System.getSecurityManager();
  1798         SecurityManager sm = System.getSecurityManager();
  1704         if (sm != null) {
  1799         if (sm != null) {
  1705             sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
  1800             sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
  1706             sm.checkRead(path);
  1801             sm.checkRead(path);
  1707         }
  1802         }
       
  1803         if (isInvalid()) {
       
  1804             return 0L;
       
  1805         }
  1708         return fs.getSpace(this, FileSystem.SPACE_TOTAL);
  1806         return fs.getSpace(this, FileSystem.SPACE_TOTAL);
  1709     }
  1807     }
  1710 
  1808 
  1711     /**
  1809     /**
  1712      * Returns the number of unallocated bytes in the partition <a
  1810      * Returns the number of unallocated bytes in the partition <a
  1719      * inaccurate by any external I/O operations including those made
  1817      * inaccurate by any external I/O operations including those made
  1720      * on the system outside of this virtual machine.  This method
  1818      * on the system outside of this virtual machine.  This method
  1721      * makes no guarantee that write operations to this file system
  1819      * makes no guarantee that write operations to this file system
  1722      * will succeed.
  1820      * will succeed.
  1723      *
  1821      *
  1724      * @return  The number of unallocated bytes on the partition <tt>0L</tt>
  1822      * @return  The number of unallocated bytes on the partition or <tt>0L</tt>
  1725      *          if the abstract pathname does not name a partition.  This
  1823      *          if the abstract pathname does not name a partition.  This
  1726      *          value will be less than or equal to the total file system size
  1824      *          value will be less than or equal to the total file system size
  1727      *          returned by {@link #getTotalSpace}.
  1825      *          returned by {@link #getTotalSpace}.
  1728      *
  1826      *
  1729      * @throws  SecurityException
  1827      * @throws  SecurityException
  1737     public long getFreeSpace() {
  1835     public long getFreeSpace() {
  1738         SecurityManager sm = System.getSecurityManager();
  1836         SecurityManager sm = System.getSecurityManager();
  1739         if (sm != null) {
  1837         if (sm != null) {
  1740             sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
  1838             sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
  1741             sm.checkRead(path);
  1839             sm.checkRead(path);
       
  1840         }
       
  1841         if (isInvalid()) {
       
  1842             return 0L;
  1742         }
  1843         }
  1743         return fs.getSpace(this, FileSystem.SPACE_FREE);
  1844         return fs.getSpace(this, FileSystem.SPACE_FREE);
  1744     }
  1845     }
  1745 
  1846 
  1746     /**
  1847     /**
  1776         SecurityManager sm = System.getSecurityManager();
  1877         SecurityManager sm = System.getSecurityManager();
  1777         if (sm != null) {
  1878         if (sm != null) {
  1778             sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
  1879             sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
  1779             sm.checkRead(path);
  1880             sm.checkRead(path);
  1780         }
  1881         }
       
  1882         if (isInvalid()) {
       
  1883             return 0L;
       
  1884         }
  1781         return fs.getSpace(this, FileSystem.SPACE_USABLE);
  1885         return fs.getSpace(this, FileSystem.SPACE_USABLE);
  1782     }
  1886     }
  1783 
  1887 
  1784     /* -- Temporary files -- */
  1888     /* -- Temporary files -- */
  1785 
  1889 
  1786     private static class TempDirectory {
  1890     private static class TempDirectory {
  1787         private TempDirectory() { }
  1891         private TempDirectory() { }
  1788 
  1892 
  1789         // temporary directory location
  1893         // temporary directory location
  1790         private static final File tmpdir = new File(fs.normalize(AccessController
  1894         private static final File tmpdir = new File(AccessController
  1791             .doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
  1895             .doPrivileged(new GetPropertyAction("java.io.tmpdir")));
  1792         static File location() {
  1896         static File location() {
  1793             return tmpdir;
  1897             return tmpdir;
  1794         }
  1898         }
  1795 
  1899 
  1796         // file name generation
  1900         // file name generation
  1897                     if (directory == null)
  2001                     if (directory == null)
  1898                         throw new SecurityException("Unable to create temporary file");
  2002                         throw new SecurityException("Unable to create temporary file");
  1899                     throw se;
  2003                     throw se;
  1900                 }
  2004                 }
  1901             }
  2005             }
       
  2006             if (f.isInvalid()) {
       
  2007                 throw new IOException("Unable to create temporary file");
       
  2008             }
  1902         } while (!fs.createFileExclusively(f.getPath()));
  2009         } while (!fs.createFileExclusively(f.getPath()));
  1903         return f;
  2010         return f;
  1904     }
  2011     }
  1905 
  2012 
  1906     /**
  2013     /**