GNU Classpath (0.95) | |
Frames | No Frames |
1: /* File.java -- Class representing a file on disk 2: Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: 40: package java.io; 41: 42: import gnu.classpath.SystemProperties; 43: 44: import java.net.MalformedURLException; 45: import java.net.URI; 46: import java.net.URISyntaxException; 47: import java.net.URL; 48: 49: /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 50: * "The Java Language Specification", ISBN 0-201-63451-1 51: * Status: Complete to version 1.3. 52: */ 53: 54: /** 55: * This class represents a file or directory on a local disk. It provides 56: * facilities for dealing with a variety of systems that use various 57: * types of path separators ("/" versus "\", for example). It also 58: * contains method useful for creating and deleting files and directories. 59: * 60: * @author Aaron M. Renn (arenn@urbanophile.com) 61: * @author Tom Tromey (tromey@cygnus.com) 62: */ 63: public class File implements Serializable, Comparable<File> 64: { 65: private static final long serialVersionUID = 301077366599181567L; 66: 67: /** 68: * This is the path separator string for the current host. This field 69: * contains the value of the <code>file.separator</code> system property. 70: * An example separator string would be "/" on the GNU system. 71: */ 72: public static final String separator = SystemProperties.getProperty("file.separator"); 73: private static final String dupSeparator = separator + separator; 74: 75: /** 76: * This is the first character of the file separator string. On many 77: * hosts (for example, on the GNU system), this represents the entire 78: * separator string. The complete separator string is obtained from the 79: * <code>file.separator</code>system property. 80: */ 81: public static final char separatorChar = separator.charAt(0); 82: 83: /** 84: * This is the string that is used to separate the host name from the 85: * path name in paths that include the host name. It is the value of 86: * the <code>path.separator</code> system property. 87: */ 88: public static final String pathSeparator 89: = SystemProperties.getProperty("path.separator"); 90: 91: /** 92: * This is the first character of the string used to separate the host name 93: * from the path name in paths that include a host. The separator string 94: * is taken from the <code>path.separator</code> system property. 95: */ 96: public static final char pathSeparatorChar = pathSeparator.charAt(0); 97: 98: /** 99: * This is the path to the file set when the object is created. It 100: * may be an absolute or relative path name. 101: */ 102: private String path; 103: 104: 105: /** 106: * The time (millisecond), when the last temporary file was created. 107: */ 108: private static long last_tmp; 109: 110: /** 111: * The number of files, created during the current millisecond. 112: */ 113: private static int n_created; 114: 115: /** 116: * This method tests whether or not the current thread is allowed to 117: * to read the file pointed to by this object. This will be true if and 118: * and only if 1) the file exists and 2) the <code>SecurityManager</code> 119: * (if any) allows access to the file via it's <code>checkRead</code> 120: * method 3) the file is readable. 121: * 122: * @return <code>true</code> if reading is allowed, 123: * <code>false</code> otherwise 124: * 125: * @exception SecurityException If the <code>SecurityManager</code> 126: * does not allow access to the file 127: */ 128: public boolean canRead() 129: { 130: // Test for existence. This also does the SecurityManager check 131: if (!exists()) 132: return false; 133: 134: return VMFile.canRead(path); 135: } 136: 137: /** 138: * This method test whether or not the current thread is allowed to 139: * write to this object. This will be true if and only if 1) The 140: * <code>SecurityManager</code> (if any) allows write access to the 141: * file and 2) The file exists and 3) The file is writable. To determine 142: * whether or not a non-existent file can be created, check the parent 143: * directory for write access. 144: * 145: * @return <code>true</code> if writing is allowed, <code>false</code> 146: * otherwise 147: * 148: * @exception SecurityException If the <code>SecurityManager</code> 149: * does not allow access to the file 150: */ 151: public boolean canWrite() 152: { 153: // First do a SecurityCheck before doing anything else. 154: checkWrite(); 155: 156: // Test for existence. This is required by the spec 157: if (! VMFile.exists(path)) 158: return false; 159: 160: if (VMFile.isDirectory(path)) 161: return VMFile.canWriteDirectory(this); 162: else 163: return VMFile.canWrite(path); 164: } 165: 166: /** 167: * This method tests whether or not the current thread is allowed to 168: * to execute the file pointed to by this object. This will be true if and 169: * and only if 1) the file exists and 2) the <code>SecurityManager</code> 170: * (if any) allows access to the file via it's <code>checkExec</code> 171: * method 3) the file is executable. 172: * 173: * @return <code>true</code> if execution is allowed, 174: * <code>false</code> otherwise 175: * 176: * @exception SecurityException If the <code>SecurityManager</code> 177: * does not allow access to the file 178: */ 179: public boolean canExecute() 180: { 181: if (!VMFile.exists(path)) 182: return false; 183: 184: checkExec(); 185: 186: return VMFile.canExecute(path); 187: } 188: 189: /** 190: * This method creates a new file of zero length with the same name as 191: * the path of this <code>File</code> object if an only if that file 192: * does not already exist. 193: * <p> 194: * A <code>SecurityManager.checkWrite</code> check is done prior 195: * to performing this action. 196: * 197: * @return <code>true</code> if the file was created, <code>false</code> if 198: * the file alread existed. 199: * 200: * @exception IOException If an I/O error occurs 201: * @exception SecurityException If the <code>SecurityManager</code> will 202: * not allow this operation to be performed. 203: * 204: * @since 1.2 205: */ 206: public boolean createNewFile() throws IOException 207: { 208: checkWrite(); 209: return VMFile.create(path); 210: } 211: /** 212: * This method deletes the file represented by this object. If this file 213: * is a directory, it must be empty in order for the delete to succeed. 214: * 215: * @return <code>true</code> if the file was deleted, <code>false</code> 216: * otherwise 217: * 218: * @exception SecurityException If deleting of the file is not allowed 219: */ 220: public synchronized boolean delete() 221: { 222: SecurityManager s = System.getSecurityManager(); 223: 224: if (s != null) 225: s.checkDelete(path); 226: 227: return VMFile.delete(path); 228: } 229: 230: /** 231: * This method tests two <code>File</code> objects for equality by 232: * comparing the path of the specified <code>File</code> against the path 233: * of this object. The two objects are equal if an only if 1) The 234: * argument is not null 2) The argument is a <code>File</code> object and 235: * 3) The path of the <code>File</code>argument is equal to the path 236: * of this object. 237: * <p> 238: * The paths of the files are determined by calling the 239: * <code>getPath()</code> 240: * method on each object. 241: * 242: * @return <code>true</code> if the two objects are equal, 243: * <code>false</code> otherwise. 244: */ 245: public boolean equals(Object obj) 246: { 247: if (! (obj instanceof File)) 248: return false; 249: 250: File other = (File) obj; 251: 252: if (VMFile.IS_CASE_SENSITIVE) 253: return path.equals(other.path); 254: else 255: return path.equalsIgnoreCase(other.path); 256: } 257: 258: /** 259: * This method tests whether or not the file represented by the object 260: * actually exists on the filesystem. 261: * 262: * @return <code>true</code> if the file exists, <code>false</code>otherwise. 263: * 264: * @exception SecurityException If reading of the file is not permitted 265: */ 266: public boolean exists() 267: { 268: checkRead(); 269: return VMFile.exists(path); 270: } 271: 272: /** 273: * This method initializes a new <code>File</code> object to represent 274: * a file with the specified path. 275: * 276: * @param name The path name of the file 277: */ 278: public File(String name) 279: { 280: path = normalizePath (name); 281: } 282: 283: // Remove duplicate and redundant separator characters. 284: private String normalizePath(String p) 285: { 286: // On Windows, convert any '/' to '\'. This appears to be the same logic 287: // that Sun's Win32 Java performs. 288: if (separatorChar == '\\') 289: { 290: p = p.replace ('/', '\\'); 291: // We have to special case the "\c:" prefix. 292: if (p.length() > 2 && p.charAt(0) == '\\' && 293: ((p.charAt(1) >= 'a' && p.charAt(1) <= 'z') || 294: (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z')) && 295: p.charAt(2) == ':') 296: p = p.substring(1); 297: } 298: 299: int dupIndex = p.indexOf(dupSeparator); 300: int plen = p.length(); 301: 302: // Special case: permit Windows UNC path prefix. 303: if (dupSeparator.equals("\\\\") && dupIndex == 0) 304: dupIndex = p.indexOf(dupSeparator, 1); 305: 306: if (dupIndex == -1) 307: { 308: // Ignore trailing separator (though on Windows "a:\", for 309: // example, is a valid and minimal path). 310: if (plen > 1 && p.charAt (plen - 1) == separatorChar) 311: { 312: if (! (separatorChar == '\\' && ((plen == 3 && p.charAt(1) == ':') 313: || (plen == 2 && p.charAt(0) == separatorChar)))) 314: return p.substring (0, plen - 1); 315: } 316: else 317: return p; 318: } 319: 320: StringBuffer newpath = new StringBuffer(plen); 321: int last = 0; 322: while (dupIndex != -1) 323: { 324: newpath.append(p.substring(last, dupIndex)); 325: // Ignore the duplicate path characters. 326: while (p.charAt(dupIndex) == separatorChar) 327: { 328: dupIndex++; 329: if (dupIndex == plen) 330: { 331: if ((separatorChar == '\\' 332: && newpath.length() == 2 333: && newpath.charAt(1) == ':') 334: || (separatorChar != '\\' && newpath.length() == 0)) 335: { 336: newpath.append(separatorChar); 337: } 338: return newpath.toString(); 339: } 340: } 341: newpath.append(separatorChar); 342: last = dupIndex; 343: dupIndex = p.indexOf(dupSeparator, last); 344: } 345: 346: // Again, ignore possible trailing separator (except special cases 347: // like "a:\" on Windows). 348: int end; 349: if (plen > 1 && p.charAt (plen - 1) == separatorChar) 350: { 351: if (separatorChar == '\\' 352: && ((plen == 3 && p.charAt(1) == ':') 353: || (plen == 2 && p.charAt(0) == separatorChar))) 354: end = plen; 355: else 356: end = plen - 1; 357: } 358: else 359: end = plen; 360: newpath.append(p.substring(last, end)); 361: 362: return newpath.toString(); 363: } 364: 365: /** 366: * This method initializes a new <code>File</code> object to represent 367: * a file in the specified named directory. The path name to the file 368: * will be the directory name plus the separator string plus the file 369: * name. If the directory path name ends in the separator string, another 370: * separator string will still be appended. 371: * 372: * @param dirPath The path to the directory the file resides in 373: * @param name The name of the file 374: */ 375: public File(String dirPath, String name) 376: { 377: if (name == null) 378: throw new NullPointerException(); 379: if (dirPath != null) 380: { 381: if (dirPath.length() > 0) 382: { 383: // Try to be smart about the number of separator characters. 384: if (dirPath.charAt(dirPath.length() - 1) == separatorChar 385: || name.length() == 0) 386: path = normalizePath(dirPath + name); 387: else 388: path = normalizePath(dirPath + separatorChar + name); 389: } 390: else 391: { 392: // If dirPath is empty, use a system dependant 393: // default prefix. 394: // Note that the leading separators in name have 395: // to be chopped off, to prevent them forming 396: // a UNC prefix on Windows. 397: if (separatorChar == '\\' /* TODO use ON_WINDOWS */) 398: { 399: int skip = 0; 400: while(name.length() > skip 401: && (name.charAt(skip) == separatorChar 402: || name.charAt(skip) == '/')) 403: { 404: skip++; 405: } 406: name = name.substring(skip); 407: } 408: path = normalizePath(separatorChar + name); 409: } 410: } 411: else 412: path = normalizePath(name); 413: } 414: 415: /** 416: * This method initializes a new <code>File</code> object to represent 417: * a file in the specified directory. If the <code>directory</code> 418: * argument is <code>null</code>, the file is assumed to be in the 419: * current directory as specified by the <code>user.dir</code> system 420: * property 421: * 422: * @param directory The directory this file resides in 423: * @param name The name of the file 424: */ 425: public File(File directory, String name) 426: { 427: this (directory == null ? null : directory.path, name); 428: } 429: 430: /** 431: * This method initializes a new <code>File</code> object to represent 432: * a file corresponding to the specified <code>file:</code> protocol URI. 433: * 434: * @param uri The URI 435: * @throws IllegalArgumentException if the URI is not hierarchical 436: */ 437: public File(URI uri) 438: { 439: if (uri == null) 440: throw new NullPointerException("uri is null"); 441: 442: if (!uri.getScheme().equals("file")) 443: throw new IllegalArgumentException("invalid uri protocol"); 444: 445: String name = uri.getPath(); 446: if (name == null) 447: throw new IllegalArgumentException("URI \"" + uri 448: + "\" is not hierarchical"); 449: path = normalizePath(name); 450: } 451: 452: /** 453: * This method returns the path of this file as an absolute path name. 454: * If the path name is already absolute, then it is returned. Otherwise 455: * the value returned is the current directory plus the separatory 456: * string plus the path of the file. The current directory is determined 457: * from the <code>user.dir</code> system property. 458: * 459: * @return The absolute path of this file 460: */ 461: public String getAbsolutePath() 462: { 463: if (isAbsolute()) 464: return path; 465: else 466: return VMFile.getAbsolutePath(path); 467: } 468: 469: /** 470: * This method returns a <code>File</code> object representing the 471: * absolute path of this object. 472: * 473: * @return A <code>File</code> with the absolute path of the object. 474: * 475: * @since 1.2 476: */ 477: public File getAbsoluteFile() 478: { 479: return new File(getAbsolutePath()); 480: } 481: 482: /** 483: * This method returns a canonical representation of the pathname of 484: * this file. The actual form of the canonical representation is 485: * system-dependent. On the GNU system, conversion to canonical 486: * form involves the removal of redundant separators, references to 487: * "." and "..", and symbolic links. 488: * <p> 489: * Note that this method, unlike the other methods which return path 490: * names, can throw an IOException. This is because native method 491: * might be required in order to resolve the canonical path 492: * 493: * @exception IOException If an error occurs 494: */ 495: public String getCanonicalPath() throws IOException 496: { 497: // On Windows, getAbsolutePath might end up calling us, so we 498: // have to special case that call to avoid infinite recursion. 499: if (separatorChar == '\\' && path.length() == 2 && 500: ((path.charAt(0) >= 'a' && path.charAt(0) <= 'z') || 501: (path.charAt(0) >= 'A' && path.charAt(0) <= 'Z')) && 502: path.charAt(1) == ':') 503: { 504: return VMFile.toCanonicalForm(path); 505: } 506: // Call getAbsolutePath first to make sure that we do the 507: // current directory handling, because the native code 508: // may have a different idea of the current directory. 509: return VMFile.toCanonicalForm(getAbsolutePath()); 510: } 511: 512: /** 513: * This method returns a <code>File</code> object representing the 514: * canonical path of this object. 515: * 516: * @return A <code>File</code> instance representing the canonical path of 517: * this object. 518: * 519: * @exception IOException If an error occurs. 520: * 521: * @since 1.2 522: */ 523: public File getCanonicalFile() throws IOException 524: { 525: return new File(getCanonicalPath()); 526: } 527: 528: /** 529: * This method returns the name of the file. This is everything in the 530: * complete path of the file after the last instance of the separator 531: * string. 532: * 533: * @return The file name 534: */ 535: public String getName() 536: { 537: return VMFile.getName(path); 538: } 539: 540: /** 541: * This method returns a <code>String</code> the represents this file's 542: * parent. <code>null</code> is returned if the file has no parent. The 543: * parent is determined via a simple operation which removes the name 544: * after the last file separator character, as determined by the platform. 545: * 546: * @return The parent directory of this file 547: */ 548: public String getParent() 549: { 550: String prefix = null; 551: int nameSeqIndex = 0; 552: 553: if (path.equals("")) 554: return null; 555: 556: // The "prefix", if present, is the leading "/" on UNIX and 557: // either the drive specifier (e.g. "C:") or the leading "\\" 558: // of a UNC network path on Windows. 559: if (separatorChar == '/' && path.charAt (0) == '/') 560: { 561: prefix = "/"; 562: nameSeqIndex = 1; 563: } 564: else if (separatorChar == '\\' && path.length() > 1) 565: { 566: if ((path.charAt (0) == '\\' && path.charAt (1) == '\\') 567: || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z') 568: || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')) 569: && path.charAt (1) == ':')) 570: { 571: prefix = path.substring (0, 2); 572: nameSeqIndex = 2; 573: } 574: } 575: 576: // According to the JDK docs, the returned parent path is the 577: // portion of the name sequence before the last separator 578: // character, if found, prefixed by the prefix, otherwise null. 579: if (nameSeqIndex < path.length()) 580: { 581: String nameSeq = path.substring (nameSeqIndex, path.length()); 582: int last = nameSeq.lastIndexOf (separatorChar); 583: if (last == -1) 584: return prefix; 585: else if (last == (nameSeq.length() - 1)) 586: // Note: The path would not have a trailing separator 587: // except for cases like "C:\" on Windows (see 588: // normalizePath( )), where Sun's JRE 1.4 returns null. 589: return null; 590: else if (last == 0) 591: last++; 592: 593: if (prefix != null) 594: return prefix + nameSeq.substring (0, last); 595: else 596: return nameSeq.substring (0, last); 597: } 598: else 599: // Sun's JRE 1.4 returns null if the prefix is the only 600: // component of the path - so "/" gives null on UNIX and 601: // "C:", "\\", etc. return null on Windows. 602: return null; 603: } 604: 605: /** 606: * This method returns a <code>File</code> object representing the parent 607: * file of this one. 608: * 609: * @return a <code>File</code> for the parent of this object. 610: * <code>null</code> 611: * will be returned if this object does not have a parent. 612: * 613: * @since 1.2 614: */ 615: public File getParentFile() 616: { 617: String parent = getParent(); 618: return parent != null ? new File(parent) : null; 619: } 620: 621: /** 622: * Returns the path name that represents this file. May be a relative 623: * or an absolute path name 624: * 625: * @return The pathname of this file 626: */ 627: public String getPath() 628: { 629: return path; 630: } 631: 632: /** 633: * This method returns a hash code representing this file. It is the 634: * hash code of the path of this file (as returned by <code>getPath()</code>) 635: * exclusived or-ed with the value 1234321. 636: * 637: * @return The hash code for this object 638: */ 639: public int hashCode() 640: { 641: if (VMFile.IS_CASE_SENSITIVE) 642: return path.hashCode() ^ 1234321; 643: else 644: return path.toLowerCase().hashCode() ^ 1234321; 645: } 646: 647: /** 648: * This method returns true if this object represents an absolute file 649: * path and false if it does not. The definition of an absolute path varies 650: * by system. As an example, on GNU systems, a path is absolute if it starts 651: * with a "/". 652: * 653: * @return <code>true</code> if this object represents an absolute 654: * file name, <code>false</code> otherwise. 655: */ 656: public boolean isAbsolute() 657: { 658: return VMFile.isAbsolute(path); 659: } 660: 661: /** 662: * This method tests whether or not the file represented by this object 663: * is a directory. In order for this method to return <code>true</code>, 664: * the file represented by this object must exist and be a directory. 665: * 666: * @return <code>true</code> if this file is a directory, <code>false</code> 667: * otherwise 668: * 669: * @exception SecurityException If reading of the file is not permitted 670: */ 671: public boolean isDirectory() 672: { 673: checkRead(); 674: return VMFile.isDirectory(path); 675: } 676: 677: /** 678: * This method tests whether or not the file represented by this object 679: * is a "plain" file. A file is a plain file if and only if it 1) Exists, 680: * 2) Is not a directory or other type of special file. 681: * 682: * @return <code>true</code> if this is a plain file, <code>false</code> 683: * otherwise 684: * 685: * @exception SecurityException If reading of the file is not permitted 686: */ 687: public boolean isFile() 688: { 689: checkRead(); 690: return VMFile.isFile(path); 691: } 692: 693: /** 694: * This method tests whether or not this file represents a "hidden" file. 695: * On GNU systems, a file is hidden if its name begins with a "." 696: * character. Files with these names are traditionally not shown with 697: * directory listing tools. 698: * 699: * @return <code>true</code> if the file is hidden, <code>false</code> 700: * otherwise. 701: * 702: * @since 1.2 703: */ 704: public boolean isHidden() 705: { 706: return VMFile.isHidden(path); 707: } 708: 709: /** 710: * This method returns the last modification time of this file. The 711: * time value returned is an abstract value that should not be interpreted 712: * as a specified time value. It is only useful for comparing to other 713: * such time values returned on the same system. In that case, the larger 714: * value indicates a more recent modification time. 715: * <p> 716: * If the file does not exist, then a value of 0 is returned. 717: * 718: * @return The last modification time of the file 719: * 720: * @exception SecurityException If reading of the file is not permitted 721: */ 722: public long lastModified() 723: { 724: checkRead(); 725: return VMFile.lastModified(path); 726: } 727: 728: /** 729: * This method returns the length of the file represented by this object, 730: * or 0 if the specified file does not exist. 731: * 732: * @return The length of the file 733: * 734: * @exception SecurityException If reading of the file is not permitted 735: */ 736: public long length() 737: { 738: checkRead(); 739: return VMFile.length(path); 740: } 741: 742: /** 743: * This method returns a array of <code>String</code>'s representing the 744: * list of files is then directory represented by this object. If this 745: * object represents a non-directory file or a non-existent file, then 746: * <code>null</code> is returned. The list of files will not contain 747: * any names such as "." or ".." which indicate the current or parent 748: * directory. Also, the names are not guaranteed to be sorted. 749: * <p> 750: * In this form of the <code>list()</code> method, a filter is specified 751: * that allows the caller to control which files are returned in the 752: * list. The <code>FilenameFilter</code> specified is called for each 753: * file returned to determine whether or not that file should be included 754: * in the list. 755: * <p> 756: * A <code>SecurityManager</code> check is made prior to reading the 757: * directory. If read access to the directory is denied, an exception 758: * will be thrown. 759: * 760: * @param filter An object which will identify files to exclude from 761: * the directory listing. 762: * 763: * @return An array of files in the directory, or <code>null</code> 764: * if this object does not represent a valid directory. 765: * 766: * @exception SecurityException If read access is not allowed to the 767: * directory by the <code>SecurityManager</code> 768: */ 769: public String[] list(FilenameFilter filter) 770: { 771: checkRead(); 772: 773: if (!exists() || !isDirectory()) 774: return null; 775: 776: // Get the list of files 777: String files[] = VMFile.list(path); 778: 779: // Check if an error occured in listInternal(). 780: // This is an unreadable directory, pretend there is nothing inside. 781: if (files == null) 782: return new String[0]; 783: 784: if (filter == null) 785: return files; 786: 787: // Apply the filter 788: int count = 0; 789: for (int i = 0; i < files.length; i++) 790: { 791: if (filter.accept(this, files[i])) 792: ++count; 793: else 794: files[i] = null; 795: } 796: 797: String[] retfiles = new String[count]; 798: count = 0; 799: for (int i = 0; i < files.length; i++) 800: if (files[i] != null) 801: retfiles[count++] = files[i]; 802: 803: return retfiles; 804: } 805: 806: /** 807: * This method returns a array of <code>String</code>'s representing the 808: * list of files is then directory represented by this object. If this 809: * object represents a non-directory file or a non-existent file, then 810: * <code>null</code> is returned. The list of files will not contain 811: * any names such as "." or ".." which indicate the current or parent 812: * directory. Also, the names are not guaranteed to be sorted. 813: * <p> 814: * A <code>SecurityManager</code> check is made prior to reading the 815: * directory. If read access to the directory is denied, an exception 816: * will be thrown. 817: * 818: * @return An array of files in the directory, or <code>null</code> if 819: * this object does not represent a valid directory. 820: * 821: * @exception SecurityException If read access is not allowed to the 822: * directory by the <code>SecurityManager</code> 823: */ 824: public String[] list() 825: { 826: return list(null); 827: } 828: 829: /** 830: * This method returns an array of <code>File</code> objects representing 831: * all the files in the directory represented by this object. If this 832: * object does not represent a directory, <code>null</code> is returned. 833: * Each of the returned <code>File</code> object is constructed with this 834: * object as its parent. 835: * <p> 836: * A <code>SecurityManager</code> check is made prior to reading the 837: * directory. If read access to the directory is denied, an exception 838: * will be thrown. 839: * 840: * @return An array of <code>File</code> objects for this directory. 841: * 842: * @exception SecurityException If the <code>SecurityManager</code> denies 843: * access to this directory. 844: * 845: * @since 1.2 846: */ 847: public File[] listFiles() 848: { 849: return listFiles((FilenameFilter) null); 850: } 851: 852: /** 853: * This method returns an array of <code>File</code> objects representing 854: * all the files in the directory represented by this object. If this 855: * object does not represent a directory, <code>null</code> is returned. 856: * Each of the returned <code>File</code> object is constructed with this 857: * object as its parent. 858: * <p> 859: * In this form of the <code>listFiles()</code> method, a filter is specified 860: * that allows the caller to control which files are returned in the 861: * list. The <code>FilenameFilter</code> specified is called for each 862: * file returned to determine whether or not that file should be included 863: * in the list. 864: * <p> 865: * A <code>SecurityManager</code> check is made prior to reading the 866: * directory. If read access to the directory is denied, an exception 867: * will be thrown. 868: * 869: * @return An array of <code>File</code> objects for this directory. 870: * 871: * @exception SecurityException If the <code>SecurityManager</code> denies 872: * access to this directory. 873: * 874: * @since 1.2 875: */ 876: public File[] listFiles(FilenameFilter filter) 877: { 878: String[] filelist = list(filter); 879: 880: if (filelist == null) 881: return null; 882: 883: File[] fobjlist = new File [filelist.length]; 884: 885: for (int i = 0; i < filelist.length; i++) 886: fobjlist [i] = new File(this, filelist [i]); 887: 888: return fobjlist; 889: } 890: 891: /** 892: * This method returns an array of <code>File</code> objects representing 893: * all the files in the directory represented by this object. If this 894: * object does not represent a directory, <code>null</code> is returned. 895: * Each of the returned <code>File</code> object is constructed with this 896: * object as its parent. 897: * <p> 898: * In this form of the <code>listFiles()</code> method, a filter is specified 899: * that allows the caller to control which files are returned in the 900: * list. The <code>FileFilter</code> specified is called for each 901: * file returned to determine whether or not that file should be included 902: * in the list. 903: * <p> 904: * A <code>SecurityManager</code> check is made prior to reading the 905: * directory. If read access to the directory is denied, an exception 906: * will be thrown. 907: * 908: * @return An array of <code>File</code> objects for this directory. 909: * 910: * @exception SecurityException If the <code>SecurityManager</code> denies 911: * access to this directory. 912: * 913: * @since 1.2 914: */ 915: public File[] listFiles(FileFilter filter) 916: { 917: File[] fobjlist = listFiles((FilenameFilter) null); 918: 919: if (fobjlist == null) 920: return null; 921: 922: if (filter == null) 923: return fobjlist; 924: 925: int count = 0; 926: for (int i = 0; i < fobjlist.length; i++) 927: if (filter.accept(fobjlist[i]) == true) 928: ++count; 929: 930: File[] final_list = new File[count]; 931: count = 0; 932: for (int i = 0; i < fobjlist.length; i++) 933: if (filter.accept(fobjlist[i]) == true) 934: { 935: final_list[count] = fobjlist[i]; 936: ++count; 937: } 938: 939: return final_list; 940: } 941: 942: /** 943: * This method returns a <code>String</code> that is the path name of the 944: * file as returned by <code>getPath</code>. 945: * 946: * @return A <code>String</code> representation of this file 947: */ 948: public String toString() 949: { 950: return path; 951: } 952: 953: /** 954: * @return A <code>URI</code> for this object. 955: */ 956: public URI toURI() 957: { 958: String abspath = getAbsolutePath(); 959: 960: if (isDirectory() || path.equals("")) 961: abspath = abspath + separatorChar; 962: 963: if (separatorChar == '\\') 964: abspath = separatorChar + abspath; 965: 966: try 967: { 968: return new URI("file", null, null, -1, 969: abspath.replace(separatorChar, '/'), 970: null, null); 971: } 972: catch (URISyntaxException use) 973: { 974: // Can't happen. 975: throw (InternalError) new InternalError("Unconvertible file: " 976: + this).initCause(use); 977: } 978: } 979: 980: /** 981: * This method returns a <code>URL</code> with the <code>file:</code> 982: * protocol that represents this file. The exact form of this URL is 983: * system dependent. 984: * 985: * @return A <code>URL</code> for this object. 986: * 987: * @exception MalformedURLException If the URL cannot be created 988: * successfully. 989: */ 990: public URL toURL() throws MalformedURLException 991: { 992: return VMFile.toURL(this); 993: } 994: 995: 996: /** 997: * This method creates a directory for the path represented by this object. 998: * 999: * @return <code>true</code> if the directory was created, 1000: * <code>false</code> otherwise 1001: * 1002: * @exception SecurityException If write access is not allowed to this file 1003: */ 1004: public boolean mkdir() 1005: { 1006: checkWrite(); 1007: return VMFile.mkdir(path); 1008: } 1009: 1010: /** 1011: * This method creates a directory for the path represented by this file. 1012: * It will also create any intervening parent directories if necessary. 1013: * 1014: * @return <code>true</code> if the directory was created, 1015: * <code>false</code> otherwise 1016: * 1017: * @exception SecurityException If write access is not allowed to this file 1018: */ 1019: public boolean mkdirs() 1020: { 1021: String parent = getParent(); 1022: if (parent == null) 1023: { 1024: return mkdir(); 1025: } 1026: 1027: File f = new File(parent); 1028: if (!f.exists()) 1029: { 1030: boolean rc = f.mkdirs(); 1031: if (rc == false) 1032: return false; 1033: } 1034: 1035: return mkdir(); 1036: } 1037: 1038: /** 1039: * This method creates a temporary file in the specified directory. If 1040: * the directory name is null, then this method uses the system temporary 1041: * directory. The files created are guaranteed not to currently exist and 1042: * the same file name will never be used twice in the same virtual 1043: * machine instance. 1044: * The system temporary directory is determined by examinging the 1045: * <code>java.io.tmpdir</code> system property. 1046: * <p> 1047: * The <code>prefix</code> parameter is a sequence of at least three 1048: * characters that are used as the start of the generated filename. The 1049: * <code>suffix</code> parameter is a sequence of characters that is used 1050: * to terminate the file name. This parameter may be <code>null</code> 1051: * and if it is, the suffix defaults to ".tmp". 1052: * <p> 1053: * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code> 1054: * method is used to verify that this operation is permitted. 1055: * 1056: * @param prefix The character prefix to use in generating the path name. 1057: * @param suffix The character suffix to use in generating the path name. 1058: * @param directory The directory to create the file in, or 1059: * <code>null</code> for the default temporary directory 1060: * 1061: * @exception IllegalArgumentException If the patterns is not valid 1062: * @exception SecurityException If there is no permission to perform 1063: * this operation 1064: * @exception IOException If an error occurs 1065: * 1066: * @since 1.2 1067: */ 1068: public static synchronized File createTempFile(String prefix, String suffix, 1069: File directory) 1070: throws IOException 1071: { 1072: // Grab the system temp directory if necessary 1073: if (directory == null) 1074: { 1075: String dirname = System.getProperty("java.io.tmpdir"); 1076: if (dirname == null) 1077: throw new IOException("Cannot determine system temporary directory"); 1078: 1079: directory = new File(dirname); 1080: if (! VMFile.exists(directory.path)) 1081: throw new IOException("System temporary directory " 1082: + directory.getName() + " does not exist."); 1083: if (! VMFile.isDirectory(directory.path)) 1084: throw new IOException("System temporary directory " 1085: + directory.getName() 1086: + " is not really a directory."); 1087: } 1088: 1089: // Check if prefix is at least 3 characters long 1090: if (prefix.length() < 3) 1091: throw new IllegalArgumentException("Prefix too short: " + prefix); 1092: 1093: // Set default value of suffix 1094: if (suffix == null) 1095: suffix = ".tmp"; 1096: 1097: // Now identify a file name and make sure it doesn't exist. 1098: File file; 1099: if (!VMFile.IS_DOS_8_3) 1100: { 1101: do 1102: { 1103: long now = System.currentTimeMillis(); 1104: if (now > last_tmp) 1105: { 1106: // The last temporary file was created more than 1 ms ago. 1107: last_tmp = now; 1108: n_created = 0; 1109: } 1110: else 1111: n_created++; 1112: 1113: String name = Long.toHexString(now); 1114: if (n_created > 0) 1115: name += '_'+Integer.toHexString(n_created); 1116: String filename = prefix + name + suffix; 1117: file = new File(directory, filename); 1118: } 1119: while (VMFile.exists(file.path)); 1120: } 1121: else 1122: { 1123: // make sure prefix is not longer than 7 characters 1124: if (prefix.length() >= 8) 1125: throw new IllegalArgumentException("Prefix too long: " + prefix + "(valid length 3..7)"); 1126: 1127: long mask = 0x000000ffffFFFFL >> (prefix.length() * 4); 1128: do 1129: { 1130: int n = (int) (System.currentTimeMillis() & mask); 1131: String filename = prefix + java.lang.Integer.toHexString(n) + suffix; 1132: file = new File(directory, filename); 1133: } 1134: while (VMFile.exists(file.path)); 1135: } 1136: 1137: // Verify that we are allowed to create this file 1138: SecurityManager sm = System.getSecurityManager(); 1139: if (sm != null) 1140: sm.checkWrite(file.getAbsolutePath()); 1141: 1142: // Now create the file and return our file object 1143: // XXX - FIXME race condition. 1144: VMFile.create(file.getAbsolutePath()); 1145: return file; 1146: } 1147: 1148: /** 1149: * This method sets the owner's read permission for the File represented by 1150: * this object. 1151: * 1152: * It is the same as calling <code>setReadable(readable, true)</code>. 1153: * 1154: * @param <code>readable</code> <code>true</code> to set read permission, 1155: * <code>false</code> to unset the read permission. 1156: * @return <code>true</code> if the file permissions are changed, 1157: * <code>false</code> otherwise. 1158: * @exception SecurityException If write access of the file is not permitted. 1159: * @see #setReadable(boolean, boolean) 1160: * @since 1.6 1161: */ 1162: public boolean setReadable(boolean readable) 1163: { 1164: return setReadable(readable, true); 1165: } 1166: 1167: /** 1168: * This method sets the read permissions for the File represented by 1169: * this object. 1170: * 1171: * If <code>ownerOnly</code> is set to <code>true</code> then only the 1172: * read permission bit for the owner of the file is changed. 1173: * 1174: * If <code>ownerOnly</code> is set to <code>false</code>, the file 1175: * permissions are changed so that the file can be read by everyone. 1176: * 1177: * On unix like systems this sets the <code>user</code>, <code>group</code> 1178: * and <code>other</code> read bits and is equal to call 1179: * <code>chmod a+r</code> on the file. 1180: * 1181: * @param <code>readable</code> <code>true</code> to set read permission, 1182: * <code>false</code> to unset the read permission. 1183: * @param <code>ownerOnly</code> <code>true</code> to set read permission 1184: * for owner only, <code>false</code> for all. 1185: * @return <code>true</code> if the file permissions are changed, 1186: * <code>false</code> otherwise. 1187: * @exception SecurityException If write access of the file is not permitted. 1188: * @see #setReadable(boolean) 1189: * @since 1.6 1190: */ 1191: public boolean setReadable(boolean readable, boolean ownerOnly) 1192: { 1193: checkWrite(); 1194: return VMFile.setReadable(path, readable, ownerOnly); 1195: } 1196: 1197: /** 1198: * This method sets the owner's write permission for the File represented by 1199: * this object. 1200: * 1201: * It is the same as calling <code>setWritable(readable, true)</code>. 1202: * 1203: * @param <code>writable</code> <code>true</code> to set write permission, 1204: * <code>false</code> to unset write permission. 1205: * @return <code>true</code> if the file permissions are changed, 1206: * <code>false</code> otherwise. 1207: * @exception SecurityException If write access of the file is not permitted. 1208: * @see #setWritable(boolean, boolean) 1209: * @since 1.6 1210: */ 1211: public boolean setWritable(boolean writable) 1212: { 1213: return setWritable(writable, true); 1214: } 1215: 1216: /** 1217: * This method sets the write permissions for the File represented by 1218: * this object. 1219: * 1220: * If <code>ownerOnly</code> is set to <code>true</code> then only the 1221: * write permission bit for the owner of the file is changed. 1222: * 1223: * If <code>ownerOnly</code> is set to <code>false</code>, the file 1224: * permissions are changed so that the file can be written by everyone. 1225: * 1226: * On unix like systems this set the <code>user</code>, <code>group</code> 1227: * and <code>other</code> write bits and is equal to call 1228: * <code>chmod a+w</code> on the file. 1229: * 1230: * @param <code>writable</code> <code>true</code> to set write permission, 1231: * <code>false</code> to unset write permission. 1232: * @param <code>ownerOnly</code> <code>true</code> to set write permission 1233: * for owner only, <code>false</code> for all. 1234: * @return <code>true</code> if the file permissions are changed, 1235: * <code>false</code> otherwise. 1236: * @exception SecurityException If write access of the file is not permitted. 1237: * @see #setWritable(boolean) 1238: * @since 1.6 1239: */ 1240: public boolean setWritable(boolean writable, boolean ownerOnly) 1241: { 1242: checkWrite(); 1243: return VMFile.setWritable(path, writable, ownerOnly); 1244: } 1245: 1246: /** 1247: * This method sets the owner's execute permission for the File represented 1248: * by this object. 1249: * 1250: * It is the same as calling <code>setExecutable(readable, true)</code>. 1251: * 1252: * @param <code>executable</code> <code>true</code> to set execute permission, 1253: * <code>false</code> to unset execute permission. 1254: * @return <code>true</code> if the file permissions are changed, 1255: * <code>false</code> otherwise. 1256: * @exception SecurityException If write access of the file is not permitted. 1257: * @see #setExecutable(boolean, boolean) 1258: * @since 1.6 1259: */ 1260: public boolean setExecutable(boolean executable) 1261: { 1262: return setExecutable(executable, true); 1263: } 1264: 1265: /** 1266: * This method sets the execute permissions for the File represented by 1267: * this object. 1268: * 1269: * If <code>ownerOnly</code> is set to <code>true</code> then only the 1270: * execute permission bit for the owner of the file is changed. 1271: * 1272: * If <code>ownerOnly</code> is set to <code>false</code>, the file 1273: * permissions are changed so that the file can be executed by everyone. 1274: * 1275: * On unix like systems this set the <code>user</code>, <code>group</code> 1276: * and <code>other</code> write bits and is equal to call 1277: * <code>chmod a+x</code> on the file. 1278: * 1279: * @param <code>executable</code> <code>true</code> to set write permission, 1280: * <code>false</code> to unset write permission. 1281: * @param <code>ownerOnly</code> <code>true</code> to set write permission 1282: * for owner only, <code>false</code> for all. 1283: * @return <code>true</code> if the file permissions are changed, 1284: * <code>false</code> otherwise. 1285: * @exception SecurityException If write access of the file is not permitted. 1286: * @see #setExecutable(boolean) 1287: * @since 1.6 1288: */ 1289: public boolean setExecutable(boolean executable, boolean ownerOnly) 1290: { 1291: checkWrite(); 1292: return VMFile.setExecutable(path, executable, ownerOnly); 1293: } 1294: 1295: /** 1296: * This method sets the file represented by this object to be read only. 1297: * A read only file or directory cannot be modified. Please note that 1298: * GNU systems allow read only files to be deleted if the directory it 1299: * is contained in is writable. 1300: * 1301: * @return <code>true</code> if the operation succeeded, <code>false</code> 1302: * otherwise. 1303: * 1304: * @exception SecurityException If the <code>SecurityManager</code> does 1305: * not allow this operation. 1306: * 1307: * @since 1.2 1308: */ 1309: public boolean setReadOnly() 1310: { 1311: // Do a security check before trying to do anything else. 1312: checkWrite(); 1313: 1314: // Test for existence. 1315: if (! VMFile.exists(path)) 1316: return false; 1317: 1318: return VMFile.setReadOnly(path); 1319: } 1320: 1321: /** 1322: * This method returns an array of filesystem roots. Some operating systems 1323: * have volume oriented filesystem. This method provides a mechanism for 1324: * determining which volumes exist. GNU systems use a single hierarchical 1325: * filesystem, so will have only one "/" filesystem root. 1326: * 1327: * @return An array of <code>File</code> objects for each filesystem root 1328: * available. 1329: * 1330: * @since 1.2 1331: */ 1332: public static File[] listRoots() 1333: { 1334: File[] roots = VMFile.listRoots(); 1335: 1336: SecurityManager s = System.getSecurityManager(); 1337: if (s != null) 1338: { 1339: // Only return roots to which the security manager permits read access. 1340: int count = roots.length; 1341: for (int i = 0; i < roots.length; i++) 1342: { 1343: try 1344: { 1345: s.checkRead (roots[i].path); 1346: } 1347: catch (SecurityException sx) 1348: { 1349: roots[i] = null; 1350: count--; 1351: } 1352: } 1353: if (count != roots.length) 1354: { 1355: File[] newRoots = new File[count]; 1356: int k = 0; 1357: for (int i = 0; i < roots.length; i++) 1358: { 1359: if (roots[i] != null) 1360: newRoots[k++] = roots[i]; 1361: } 1362: roots = newRoots; 1363: } 1364: } 1365: return roots; 1366: } 1367: 1368: /** 1369: * This method creates a temporary file in the system temporary directory. 1370: * The files created are guaranteed not to currently exist and the same file 1371: * name will never be used twice in the same virtual machine instance. The 1372: * system temporary directory is determined by examinging the 1373: * <code>java.io.tmpdir</code> system property. 1374: * <p> 1375: * The <code>prefix</code> parameter is a sequence of at least three 1376: * characters that are used as the start of the generated filename. The 1377: * <code>suffix</code> parameter is a sequence of characters that is used 1378: * to terminate the file name. This parameter may be <code>null</code> 1379: * and if it is, the suffix defaults to ".tmp". 1380: * <p> 1381: * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code> 1382: * method is used to verify that this operation is permitted. 1383: * <p> 1384: * This method is identical to calling 1385: * <code>createTempFile(prefix, suffix, null)</code>. 1386: * 1387: * @param prefix The character prefix to use in generating the path name. 1388: * @param suffix The character suffix to use in generating the path name. 1389: * 1390: * @exception IllegalArgumentException If the prefix or suffix are not valid. 1391: * @exception SecurityException If there is no permission to perform 1392: * this operation 1393: * @exception IOException If an error occurs 1394: */ 1395: public static File createTempFile(String prefix, String suffix) 1396: throws IOException 1397: { 1398: return createTempFile(prefix, suffix, null); 1399: } 1400: 1401: /** 1402: * This method compares the specified <code>File</code> to this one 1403: * to test for equality. It does this by comparing the canonical path names 1404: * of the files. 1405: * <p> 1406: * The canonical paths of the files are determined by calling the 1407: * <code>getCanonicalPath</code> method on each object. 1408: * <p> 1409: * This method returns a 0 if the specified <code>Object</code> is equal 1410: * to this one, a negative value if it is less than this one 1411: * a positive value if it is greater than this one. 1412: * 1413: * @return An integer as described above 1414: * 1415: * @since 1.2 1416: */ 1417: public int compareTo(File other) 1418: { 1419: if (VMFile.IS_CASE_SENSITIVE) 1420: return path.compareTo (other.path); 1421: else 1422: return path.compareToIgnoreCase (other.path); 1423: } 1424: 1425: /** 1426: * This method renames the file represented by this object to the path 1427: * of the file represented by the argument <code>File</code>. 1428: * 1429: * @param dest The <code>File</code> object representing the target name 1430: * 1431: * @return <code>true</code> if the rename succeeds, <code>false</code> 1432: * otherwise. 1433: * 1434: * @exception SecurityException If write access is not allowed to the 1435: * file by the <code>SecurityMananger</code>. 1436: */ 1437: public synchronized boolean renameTo(File dest) 1438: { 1439: checkWrite(); 1440: dest.checkWrite(); 1441: // Call our native rename method 1442: return VMFile.renameTo(path, dest.path); 1443: } 1444: 1445: /** 1446: * This method sets the modification time on the file to the specified 1447: * value. This is specified as the number of seconds since midnight 1448: * on January 1, 1970 GMT. 1449: * 1450: * @param time The desired modification time. 1451: * 1452: * @return <code>true</code> if the operation succeeded, <code>false</code> 1453: * otherwise. 1454: * 1455: * @exception IllegalArgumentException If the specified time is negative. 1456: * @exception SecurityException If the <code>SecurityManager</code> will 1457: * not allow this operation. 1458: * 1459: * @since 1.2 1460: */ 1461: public boolean setLastModified(long time) 1462: { 1463: if (time < 0) 1464: throw new IllegalArgumentException("Negative modification time: " + time); 1465: 1466: checkWrite(); 1467: return VMFile.setLastModified(path, time); 1468: } 1469: 1470: private void checkWrite() 1471: { 1472: // Check the SecurityManager 1473: SecurityManager s = System.getSecurityManager(); 1474: 1475: if (s != null) 1476: s.checkWrite(path); 1477: } 1478: 1479: private void checkRead() 1480: { 1481: // Check the SecurityManager 1482: SecurityManager s = System.getSecurityManager(); 1483: 1484: if (s != null) 1485: s.checkRead(path); 1486: } 1487: 1488: private void checkExec() 1489: { 1490: // Check the SecurityManager 1491: SecurityManager s = System.getSecurityManager(); 1492: 1493: if (s != null) 1494: s.checkExec(path); 1495: } 1496: 1497: /** 1498: * Calling this method requests that the file represented by this object 1499: * be deleted when the virtual machine exits. Note that this request cannot 1500: * be cancelled. Also, it will only be carried out if the virtual machine 1501: * exits normally. 1502: * 1503: * @exception SecurityException If deleting of the file is not allowed 1504: * 1505: * @since 1.2 1506: */ 1507: public void deleteOnExit() 1508: { 1509: // Check the SecurityManager 1510: SecurityManager sm = System.getSecurityManager(); 1511: if (sm != null) 1512: sm.checkDelete(path); 1513: 1514: DeleteFileHelper.add(this); 1515: } 1516: 1517: private void writeObject(ObjectOutputStream oos) throws IOException 1518: { 1519: oos.defaultWriteObject(); 1520: oos.writeChar(separatorChar); 1521: } 1522: 1523: private void readObject(ObjectInputStream ois) 1524: throws ClassNotFoundException, IOException 1525: { 1526: ois.defaultReadObject(); 1527: 1528: // If the file was from an OS with a different dir separator, 1529: // fixup the path to use the separator on this OS. 1530: char oldSeparatorChar = ois.readChar(); 1531: 1532: if (oldSeparatorChar != separatorChar) 1533: path = path.replace(oldSeparatorChar, separatorChar); 1534: } 1535: 1536: } // class File
GNU Classpath (0.95) |