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