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.
5 This file is part of GNU Classpath.
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)
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.
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
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
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. */
42 import java.net.MalformedURLException;
44 import java.net.URISyntaxException;
46 import gnu.classpath.Configuration;
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.
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.
59 * @author Aaron M. Renn (arenn@urbanophile.com)
60 * @author Tom Tromey (tromey@cygnus.com)
62 public class File implements Serializable, Comparable
64 private static final long serialVersionUID = 301077366599181567L;
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;
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;
77 // QUERY arguments to attr function.
78 private final static int MODIFIED = 0;
79 private final static int LENGTH = 1;
81 private final native long attr (int query);
82 // On OSF1 V5.0, `stat' is a macro. It is easiest to use the name
83 // `_stat' instead. We do the same thing for `_access' just in
85 private final native boolean _access (int query);
86 private final native boolean _stat (int query);
89 * This is the path separator string for the current host. This field
90 * contains the value of the <code>file.separator</code> system property.
91 * An example separator string would be "/" on the GNU system.
93 public static final String separator = System.getProperty("file.separator");
94 private static final String dupSeparator = separator + separator;
97 * This is the first character of the file separator string. On many
98 * hosts (for example, on the GNU system), this represents the entire
99 * separator string. The complete separator string is obtained from the
100 * <code>file.separator</code>system property.
102 public static final char separatorChar = separator.charAt(0);
105 * This is the string that is used to separate the host name from the
106 * path name in paths than include the host name. It is the value of
107 * the <code>path.separator</code> system property.
109 public static final String pathSeparator
110 = System.getProperty("path.separator");
113 * This is the first character of the string used to separate the host name
114 * from the path name in paths that include a host. The separator string
115 * is taken from the <code>path.separator</code> system property.
117 public static final char pathSeparatorChar = pathSeparator.charAt(0);
119 static final String tmpdir = System.getProperty("java.io.tmpdir");
120 static int maxPathLen;
121 static boolean caseSensitive;
125 if (Configuration.INIT_LOAD_LIBRARY)
127 System.loadLibrary("javaio");
133 // Native function called at class initialization. This should should
134 // set the maxPathLen and caseSensitive variables.
135 private static native void init_native();
138 * This is the path to the file set when the object is created. It
139 * may be an absolute or relative path name.
143 // We keep a counter for use by createTempFile. We choose the first
144 // value randomly to try to avoid clashes with other VMs.
145 private static long counter = Double.doubleToLongBits (Math.random());
148 * This method tests whether or not the current thread is allowed to
149 * to read the file pointed to by this object. This will be true if and
150 * and only if 1) the file exists and 2) the <code>SecurityManager</code>
151 * (if any) allows access to the file via it's <code>checkRead</code>
152 * method 3) the file is readable.
154 * @return <code>true</code> if reading is allowed,
155 * <code>false</code> otherwise
157 * @exception SecurityException If the <code>SecurityManager</code>
158 * does not allow access to the file
160 public boolean canRead()
163 return _access (READ);
167 * This method test whether or not the current thread is allowed to
168 * write to this object. This will be true if and only if 1) The
169 * <code>SecurityManager</code> (if any) allows write access to the
170 * file and 2) The file exists and 3) The file is writable. To determine
171 * whether or not a non-existent file can be created, check the parent
172 * directory for write access.
174 * @return <code>true</code> if writing is allowed, <code>false</code>
177 * @exception SecurityException If the <code>SecurityManager</code>
178 * does not allow access to the file
180 public boolean canWrite()
183 return _access (WRITE);
187 * This method tests whether or not the current thread is allowed to
188 * to execute the file pointed to by this object. This will be true if and
189 * and only if 1) the file exists and 2) the <code>SecurityManager</code>
190 * (if any) allows access to the file via it's <code>checkExec</code>
191 * method 3) the file is executable.
193 * @return <code>true</code> if execution is allowed,
194 * <code>false</code> otherwise
196 * @exception SecurityException If the <code>SecurityManager</code>
197 * does not allow access to the file
199 public boolean canExecute()
204 return _access (EXEC);
207 private native boolean performCreate() throws IOException;
210 * This method creates a new file of zero length with the same name as
211 * the path of this <code>File</code> object if an only if that file
212 * does not already exist.
214 * A <code>SecurityManager.checkWrite</code> check is done prior
215 * to performing this action.
217 * @return <code>true</code> if the file was created, <code>false</code> if
218 * the file alread existed.
220 * @exception IOException If an I/O error occurs
221 * @exception SecurityException If the <code>SecurityManager</code> will
222 * not allow this operation to be performed.
226 public boolean createNewFile() throws IOException
229 return performCreate();
233 * This native method handles the actual deleting of the file
235 private native boolean performDelete();
238 * This method deletes the file represented by this object. If this file
239 * is a directory, it must be empty in order for the delete to succeed.
241 * @return <code>true</code> if the file was deleted, <code>false</code>
244 * @exception SecurityException If deleting of the file is not allowed
246 public synchronized boolean delete()
248 SecurityManager s = System.getSecurityManager();
253 return performDelete();
257 * This method tests two <code>File</code> objects for equality by
258 * comparing the path of the specified <code>File</code> against the path
259 * of this object. The two objects are equal if an only if 1) The
260 * argument is not null 2) The argument is a <code>File</code> object and
261 * 3) The path of the <code>File</code>argument is equal to the path
264 * The paths of the files are determined by calling the
265 * <code>getPath()</code>
266 * method on each object.
268 * @return <code>true</code> if the two objects are equal,
269 * <code>false</code> otherwise.
271 public boolean equals(Object obj)
273 if (! (obj instanceof File))
276 File other = (File) obj;
279 return path.equals(other.path);
281 return path.equalsIgnoreCase(other.path);
285 * This method tests whether or not the file represented by the
286 * object actually exists on the filesystem.
288 private boolean internalExists()
290 return _access (EXISTS);
294 * This method tests whether or not the file represented by the object
295 * actually exists on the filesystem.
297 * @return <code>true</code> if the file exists, <code>false</code>otherwise.
299 * @exception SecurityException If reading of the file is not permitted
301 public boolean exists()
304 return internalExists();
308 * This method initializes a new <code>File</code> object to represent
309 * a file with the specified path.
311 * @param name The path name of the file
313 public File(String name)
315 path = normalizePath (name);
318 // Remove duplicate and redundant separator characters.
319 private String normalizePath(String p)
321 // On Windows, convert any '/' to '\'. This appears to be the same logic
322 // that Sun's Win32 Java performs.
323 if (separatorChar == '\\')
325 p = p.replace ('/', '\\');
326 // We have to special case the "\c:" prefix.
327 if (p.length() > 2 && p.charAt(0) == '\\' &&
328 ((p.charAt(1) >= 'a' && p.charAt(1) <= 'z') ||
329 (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z')) &&
334 int dupIndex = p.indexOf(dupSeparator);
335 int plen = p.length();
337 // Special case: permit Windows UNC path prefix.
338 if (dupSeparator.equals("\\\\") && dupIndex == 0)
339 dupIndex = p.indexOf(dupSeparator, 1);
343 // Ignore trailing separator (though on Windows "a:\", for
344 // example, is a valid and minimal path).
345 if (plen > 1 && p.charAt (plen - 1) == separatorChar)
347 if (! (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':'))
348 return p.substring (0, plen - 1);
354 StringBuffer newpath = new StringBuffer(plen);
356 while (dupIndex != -1)
358 newpath.append(p.substring(last, dupIndex));
359 // Ignore the duplicate path characters.
360 while (p.charAt(dupIndex) == separatorChar)
363 if (dupIndex == plen)
364 return newpath.toString();
366 newpath.append(separatorChar);
368 dupIndex = p.indexOf(dupSeparator, last);
371 // Again, ignore possible trailing separator (except special cases
372 // like "a:\" on Windows).
374 if (plen > 1 && p.charAt (plen - 1) == separatorChar)
376 if (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':')
383 newpath.append(p.substring(last, end));
385 return newpath.toString();
389 * This method initializes a new <code>File</code> object to represent
390 * a file in the specified named directory. The path name to the file
391 * will be the directory name plus the separator string plus the file
392 * name. If the directory path name ends in the separator string, another
393 * separator string will still be appended.
395 * @param dirPath The path to the directory the file resides in
396 * @param name The name of the file
398 public File(String dirPath, String name)
401 throw new NullPointerException();
404 if (dirPath.length() > 0)
406 // Try to be smart about the number of separator characters.
407 if (dirPath.charAt(dirPath.length() - 1) == separatorChar
408 || name.length() == 0)
409 path = normalizePath(dirPath + name);
411 path = normalizePath(dirPath + separatorChar + name);
415 // If dirPath is empty, use a system dependant
417 // Note that the leading separators in name have
418 // to be chopped off, to prevent them forming
419 // a UNC prefix on Windows.
420 if (separatorChar == '\\' /* TODO use ON_WINDOWS */)
423 while(name.length() > skip
424 && (name.charAt(skip) == separatorChar
425 || name.charAt(skip) == '/'))
429 name = name.substring(skip);
431 path = normalizePath(separatorChar + name);
435 path = normalizePath(name);
439 * This method initializes a new <code>File</code> object to represent
440 * a file in the specified directory. If the <code>directory</code>
441 * argument is <code>null</code>, the file is assumed to be in the
442 * current directory as specified by the <code>user.dir</code> system
445 * @param directory The directory this file resides in
446 * @param name The name of the file
448 public File(File directory, String name)
450 this (directory == null ? null : directory.path, name);
454 * This method initializes a new <code>File</code> object to represent
455 * a file corresponding to the specified <code>file:</code> protocol URI.
457 * @param uri The uri.
462 throw new NullPointerException("uri is null");
464 if (!uri.getScheme().equals("file"))
465 throw new IllegalArgumentException("invalid uri protocol");
467 String name = uri.getPath();
469 throw new IllegalArgumentException("URI \"" + uri
470 + "\" is not hierarchical");
471 path = normalizePath(name);
475 * This method returns the path of this file as an absolute path name.
476 * If the path name is already absolute, then it is returned. Otherwise
477 * the value returned is the current directory plus the separatory
478 * string plus the path of the file. The current directory is determined
479 * from the <code>user.dir</code> system property.
481 * @return The absolute path of this file
483 public String getAbsolutePath()
487 else if (separatorChar == '\\'
488 && path.length() > 0 && path.charAt (0) == '\\')
490 // On Windows, even if the path starts with a '\\' it is not
491 // really absolute until we prefix the drive specifier from
492 // the current working directory to it.
493 return System.getProperty ("user.dir").substring (0, 2) + path;
495 else if (separatorChar == '\\'
496 && path.length() > 1 && path.charAt (1) == ':'
497 && ((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
498 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')))
500 // On Windows, a process has a current working directory for
501 // each drive and a path like "G:foo\bar" would mean the
502 // absolute path "G:\wombat\foo\bar" if "\wombat" is the
503 // working directory on the G drive.
504 String drvDir = null;
507 drvDir = new File (path.substring (0, 2)).getCanonicalPath();
509 catch (IOException e)
511 drvDir = path.substring (0, 2) + "\\";
514 // Note: this would return "C:\\." for the path "C:.", if "\"
515 // is the working folder on the C drive, but this is
516 // consistent with what Sun's JRE 1.4.1.01 actually returns!
517 if (path.length() > 2)
518 return drvDir + '\\' + path.substring (2, path.length());
523 return System.getProperty ("user.dir") + separatorChar + path;
527 * This method returns a <code>File</code> object representing the
528 * absolute path of this object.
530 * @return A <code>File</code> with the absolute path of the object.
534 public File getAbsoluteFile()
536 return new File(getAbsolutePath());
540 * This method returns a canonical representation of the pathname of
541 * this file. The actual form of the canonical representation is
542 * system-dependent. On the GNU system, conversion to canonical
543 * form involves the removal of redundant separators, references to
544 * "." and "..", and symbolic links.
546 * Note that this method, unlike the other methods which return path
547 * names, can throw an IOException. This is because native method
548 * might be required in order to resolve the canonical path
550 * @exception IOException If an error occurs
552 public native String getCanonicalPath() throws IOException;
555 * This method returns a <code>File</code> object representing the
556 * canonical path of this object.
558 * @return A <code>File</code> instance representing the canonical path of
561 * @exception IOException If an error occurs.
565 public File getCanonicalFile() throws IOException
567 return new File(getCanonicalPath());
571 * This method returns the name of the file. This is everything in the
572 * complete path of the file after the last instance of the separator
575 * @return The file name
577 public String getName()
579 int nameSeqIndex = 0;
581 if (separatorChar == '\\' && path.length() > 1)
583 // On Windows, ignore the drive specifier or the leading '\\'
584 // of a UNC network path, if any (a.k.a. the "prefix").
585 if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
586 || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
587 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
588 && path.charAt (1) == ':'))
590 if (path.length() > 2)
598 = (nameSeqIndex > 0 ? path.substring (nameSeqIndex) : path);
600 int last = nameSeq.lastIndexOf (separatorChar);
602 return nameSeq.substring (last + 1);
606 * This method returns a <code>String</code> the represents this file's
607 * parent. <code>null</code> is returned if the file has no parent. The
608 * parent is determined via a simple operation which removes the
610 * @return The parent directory of this file
612 public String getParent()
614 String prefix = null;
615 int nameSeqIndex = 0;
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) == '/')
625 else if (separatorChar == '\\' && path.length() > 1)
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) == ':'))
632 prefix = path.substring (0, 2);
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())
642 String nameSeq = path.substring (nameSeqIndex, path.length());
643 int last = nameSeq.lastIndexOf (separatorChar);
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.
655 return prefix + nameSeq.substring (0, last);
657 return nameSeq.substring (0, last);
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.
667 * This method returns a <code>File</code> object representing the parent
670 * @return a <code>File</code> for the parent of this object.
672 * will be returned if this object does not have a parent.
676 public File getParentFile()
678 String parent = getParent();
679 return parent != null ? new File(parent) : null;
683 * Returns the path name that represents this file. May be a relative
684 * or an absolute path name
686 * @return The pathname of this file
688 public String getPath()
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.
698 * @return The hash code for this object
700 public int hashCode()
703 return path.hashCode() ^ 1234321;
705 return path.toLowerCase().hashCode() ^ 1234321;
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
714 * @return <code>true</code> if this object represents an absolute
715 * file name, <code>false</code> otherwise.
717 public native boolean isAbsolute();
720 * This method tests whether or not the file represented by this
721 * object is a directory.
723 private boolean internalIsDirectory()
725 return _stat (DIRECTORY);
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.
733 * @return <code>true</code> if this file is a directory, <code>false</code>
736 * @exception SecurityException If reading of the file is not permitted
738 public boolean isDirectory()
741 return internalIsDirectory();
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.
749 * @return <code>true</code> if this is a plain file, <code>false</code>
752 * @exception SecurityException If reading of the file is not permitted
754 public boolean isFile()
757 return _stat (ISFILE);
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.
766 * @return <code>true</code> if the file is hidden, <code>false</code>
771 public boolean isHidden()
774 return _stat (ISHIDDEN);
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.
784 * If the file does not exist, then a value of 0 is returned.
786 * @return The last modification time of the file
788 * @exception SecurityException If reading of the file is not permitted
790 public long lastModified()
793 return attr (MODIFIED);
797 * This method returns the length of the file represented by this object,
798 * or 0 if the specified file does not exist.
800 * @return The length of the file
802 * @exception SecurityException If reading of the file is not permitted
807 return attr (LENGTH);
811 * This native function actually produces the list of file in this
814 private final native Object[] performList (FilenameFilter filter,
815 FileFilter fileFilter,
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.
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
832 * A <code>SecurityManager</code> check is made prior to reading the
833 * directory. If read access to the directory is denied, an exception
836 * @param filter An object which will identify files to exclude from
837 * the directory listing.
839 * @return An array of files in the directory, or <code>null</code>
840 * if this object does not represent a valid directory.
842 * @exception SecurityException If read access is not allowed to the
843 * directory by the <code>SecurityManager</code>
845 public String[] list(FilenameFilter filter)
848 return (String[]) performList (filter, null, String.class);
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.
859 * A <code>SecurityManager</code> check is made prior to reading the
860 * directory. If read access to the directory is denied, an exception
863 * @return An array of files in the directory, or <code>null</code> if
864 * this object does not represent a valid directory.
866 * @exception SecurityException If read access is not allowed to the
867 * directory by the <code>SecurityManager</code>
869 public String[] list()
872 return (String[]) performList (null, null, String.class);
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.
882 * A <code>SecurityManager</code> check is made prior to reading the
883 * directory. If read access to the directory is denied, an exception
886 * @return An array of <code>File</code> objects for this directory.
888 * @exception SecurityException If the <code>SecurityManager</code> denies
889 * access to this directory.
893 public File[] listFiles()
896 return (File[]) performList (null, null, File.class);
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.
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
912 * A <code>SecurityManager</code> check is made prior to reading the
913 * directory. If read access to the directory is denied, an exception
916 * @return An array of <code>File</code> objects for this directory.
918 * @exception SecurityException If the <code>SecurityManager</code> denies
919 * access to this directory.
923 public File[] listFiles(FilenameFilter filter)
926 return (File[]) performList (filter, null, File.class);
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.
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
942 * A <code>SecurityManager</code> check is made prior to reading the
943 * directory. If read access to the directory is denied, an exception
946 * @return An array of <code>File</code> objects for this directory.
948 * @exception SecurityException If the <code>SecurityManager</code> denies
949 * access to this directory.
953 public File[] listFiles(FileFilter filter)
956 return (File[]) performList (null, filter, File.class);
960 * This method returns a <code>String</code> that is the path name of the
961 * file as returned by <code>getPath</code>.
963 * @return A <code>String</code> representation of this file
965 public String toString()
971 * @return A <code>URI</code> for this object.
975 String abspath = getAbsolutePath();
978 abspath = abspath + separator;
982 return new URI("file", abspath.replace(separatorChar, '/'), null);
984 catch (URISyntaxException use)
987 throw new RuntimeException(use);
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
996 * @return A <code>URL</code> for this object.
998 * @exception MalformedURLException If the URL cannot be created
1001 public URL toURL() throws MalformedURLException
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() ? "/" : ""));
1009 return new URL ("file:" + getAbsolutePath()
1010 + (isDirectory() ? "/" : ""));
1014 * This native method actually creates the directory
1016 private final native boolean performMkdir();
1019 * This method creates a directory for the path represented by this object.
1021 * @return <code>true</code> if the directory was created,
1022 * <code>false</code> otherwise
1024 * @exception SecurityException If write access is not allowed to this file
1026 public boolean mkdir()
1029 return performMkdir();
1032 private static boolean mkdirs (File x)
1034 if (x.isDirectory())
1036 String p = x.getPath();
1037 String parent = x.getParent();
1049 * This method creates a directory for the path represented by this file.
1050 * It will also create any intervening parent directories if necessary.
1052 * @return <code>true</code> if the directory was created,
1053 * <code>false</code> otherwise
1055 * @exception SecurityException If write access is not allowed to this file
1057 public boolean mkdirs()
1062 return mkdirs (new File (path));
1065 private static synchronized String nextValue()
1067 return Long.toString(counter++, Character.MAX_RADIX);
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
1076 * The system temporary directory is determined by examinging the
1077 * <code>java.io.tmpdir</code> system property.
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".
1085 * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1086 * method is used to verify that this operation is permitted.
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
1093 * @exception IllegalArgumentException If the patterns is not valid
1094 * @exception SecurityException If there is no permission to perform
1096 * @exception IOException If an error occurs
1100 public static File createTempFile(String prefix, String suffix,
1104 // Grab the system temp directory if necessary
1105 if (directory == null)
1107 String dirname = tmpdir;
1108 if (dirname == null)
1109 throw new IOException("Cannot determine system temporary directory");
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.");
1121 // Check if prefix is at least 3 characters long
1122 if (prefix.length() < 3)
1123 throw new IllegalArgumentException("Prefix too short: " + prefix);
1125 // Set default value of suffix
1129 // Truncation rules.
1130 // `6' is the number of characters we generate.
1131 if (prefix.length() + 6 + suffix.length() > maxPathLen)
1134 if (suffix.charAt(0) == '.')
1136 suffix = suffix.substring(0, suf_len);
1137 if (prefix.length() + 6 + suf_len > maxPathLen)
1138 prefix = prefix.substring(0, maxPathLen - 6 - suf_len);
1143 // How many times should we try? We choose 100.
1144 for (int i = 0; i < 100; ++i)
1147 String t = "ZZZZZZ" + nextValue();
1148 String l = prefix + t.substring(t.length() - 6) + suffix;
1151 f = new File(directory, l);
1152 if (f.createNewFile())
1155 catch (IOException ignored)
1160 throw new IOException ("cannot create temporary file");
1164 * This native method sets file permissions.
1166 private native boolean setFilePermissions(boolean enable, boolean ownerOnly,
1170 * This method sets the owner's read permission for the File represented by
1173 * It is the same as calling <code>setReadable(readable, true)</code>.
1175 * @param <code>readable</code> <code>true</code> to set read permission,
1176 * <code>false</code> to unset the read permission.
1177 * @return <code>true</code> if the file permissions are changed,
1178 * <code>false</code> otherwise.
1179 * @exception SecurityException If write access of the file is not permitted.
1180 * @see #setReadable(boolean, boolean)
1183 public boolean setReadable(boolean readable)
1185 return setReadable(readable, true);
1189 * This method sets the read permissions for the File represented by
1192 * If <code>ownerOnly</code> is set to <code>true</code> then only the
1193 * read permission bit for the owner of the file is changed.
1195 * If <code>ownerOnly</code> is set to <code>false</code>, the file
1196 * permissions are changed so that the file can be read by everyone.
1198 * On unix like systems this sets the <code>user</code>, <code>group</code>
1199 * and <code>other</code> read bits and is equal to call
1200 * <code>chmod a+r</code> on the file.
1202 * @param <code>readable</code> <code>true</code> to set read permission,
1203 * <code>false</code> to unset the read permission.
1204 * @param <code>ownerOnly</code> <code>true</code> to set read permission
1205 * for owner only, <code>false</code> for all.
1206 * @return <code>true</code> if the file permissions are changed,
1207 * <code>false</code> otherwise.
1208 * @exception SecurityException If write access of the file is not permitted.
1209 * @see #setReadable(boolean)
1212 public boolean setReadable(boolean readable, boolean ownerOnly)
1215 return setFilePermissions(readable, ownerOnly, READ);
1219 * This method sets the owner's write permission for the File represented by
1222 * It is the same as calling <code>setWritable(readable, true)</code>.
1224 * @param <code>writable</code> <code>true</code> to set write permission,
1225 * <code>false</code> to unset write permission.
1226 * @return <code>true</code> if the file permissions are changed,
1227 * <code>false</code> otherwise.
1228 * @exception SecurityException If write access of the file is not permitted.
1229 * @see #setWritable(boolean, boolean)
1232 public boolean setWritable(boolean writable)
1234 return setWritable(writable, true);
1238 * This method sets the write permissions for the File represented by
1241 * If <code>ownerOnly</code> is set to <code>true</code> then only the
1242 * write permission bit for the owner of the file is changed.
1244 * If <code>ownerOnly</code> is set to <code>false</code>, the file
1245 * permissions are changed so that the file can be written by everyone.
1247 * On unix like systems this set the <code>user</code>, <code>group</code>
1248 * and <code>other</code> write bits and is equal to call
1249 * <code>chmod a+w</code> on the file.
1251 * @param <code>writable</code> <code>true</code> to set write permission,
1252 * <code>false</code> to unset write permission.
1253 * @param <code>ownerOnly</code> <code>true</code> to set write permission
1254 * for owner only, <code>false</code> for all.
1255 * @return <code>true</code> if the file permissions are changed,
1256 * <code>false</code> otherwise.
1257 * @exception SecurityException If write access of the file is not permitted.
1258 * @see #setWritable(boolean)
1261 public boolean setWritable(boolean writable, boolean ownerOnly)
1264 return setFilePermissions(writable, ownerOnly, WRITE);
1268 * This method sets the owner's execute permission for the File represented
1271 * It is the same as calling <code>setExecutable(readable, true)</code>.
1273 * @param <code>executable</code> <code>true</code> to set execute permission,
1274 * <code>false</code> to unset execute permission.
1275 * @return <code>true</code> if the file permissions are changed,
1276 * <code>false</code> otherwise.
1277 * @exception SecurityException If write access of the file is not permitted.
1278 * @see #setExecutable(boolean, boolean)
1281 public boolean setExecutable(boolean executable)
1283 return setExecutable(executable, true);
1287 * This method sets the execute permissions for the File represented by
1290 * If <code>ownerOnly</code> is set to <code>true</code> then only the
1291 * execute permission bit for the owner of the file is changed.
1293 * If <code>ownerOnly</code> is set to <code>false</code>, the file
1294 * permissions are changed so that the file can be executed by everyone.
1296 * On unix like systems this set the <code>user</code>, <code>group</code>
1297 * and <code>other</code> write bits and is equal to call
1298 * <code>chmod a+x</code> on the file.
1300 * @param <code>executable</code> <code>true</code> to set write permission,
1301 * <code>false</code> to unset write permission.
1302 * @param <code>ownerOnly</code> <code>true</code> to set write permission
1303 * for owner only, <code>false</code> for all.
1304 * @return <code>true</code> if the file permissions are changed,
1305 * <code>false</code> otherwise.
1306 * @exception SecurityException If write access of the file is not permitted.
1307 * @see #setExecutable(boolean)
1310 public boolean setExecutable(boolean executable, boolean ownerOnly)
1313 return setFilePermissions(executable, ownerOnly, EXEC);
1317 * This native method sets the permissions to make the file read only.
1319 private native boolean performSetReadOnly();
1322 * This method sets the file represented by this object to be read only.
1323 * A read only file or directory cannot be modified. Please note that
1324 * GNU systems allow read only files to be deleted if the directory it
1325 * is contained in is writable.
1327 * @return <code>true</code> if the operation succeeded, <code>false</code>
1330 * @exception SecurityException If the <code>SecurityManager</code> does
1331 * not allow this operation.
1335 public boolean setReadOnly()
1337 // Do a security check before trying to do anything else.
1339 return performSetReadOnly();
1342 private static native File[] performListRoots();
1345 * This method returns an array of filesystem roots. Some operating systems
1346 * have volume oriented filesystem. This method provides a mechanism for
1347 * determining which volumes exist. GNU systems use a single hierarchical
1348 * filesystem, so will have only one "/" filesystem root.
1350 * @return An array of <code>File</code> objects for each filesystem root
1355 public static File[] listRoots()
1357 File[] roots = performListRoots();
1359 SecurityManager s = System.getSecurityManager();
1362 // Only return roots to which the security manager permits read access.
1363 int count = roots.length;
1364 for (int i = 0; i < roots.length; i++)
1368 s.checkRead (roots[i].path);
1370 catch (SecurityException sx)
1376 if (count != roots.length)
1378 File[] newRoots = new File[count];
1380 for (int i=0; i < roots.length; i++)
1382 if (roots[i] != null)
1383 newRoots[k++] = roots[i];
1392 * This method creates a temporary file in the system temporary directory.
1393 * The files created are guaranteed not to currently exist and the same file
1394 * name will never be used twice in the same virtual machine instance. The
1395 * system temporary directory is determined by examinging the
1396 * <code>java.io.tmpdir</code> system property.
1398 * The <code>prefix</code> parameter is a sequence of at least three
1399 * characters that are used as the start of the generated filename. The
1400 * <code>suffix</code> parameter is a sequence of characters that is used
1401 * to terminate the file name. This parameter may be <code>null</code>
1402 * and if it is, the suffix defaults to ".tmp".
1404 * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1405 * method is used to verify that this operation is permitted.
1407 * This method is identical to calling
1408 * <code>createTempFile(prefix, suffix, null)</code>.
1410 * @param prefix The character prefix to use in generating the path name.
1411 * @param suffix The character suffix to use in generating the path name.
1413 * @exception IllegalArgumentException If the prefix or suffix are not valid.
1414 * @exception SecurityException If there is no permission to perform
1416 * @exception IOException If an error occurs
1418 public static File createTempFile(String prefix, String suffix)
1421 return createTempFile(prefix, suffix, null);
1425 * This method compares the specified <code>File</code> to this one
1426 * to test for equality. It does this by comparing the canonical path names
1429 * The canonical paths of the files are determined by calling the
1430 * <code>getCanonicalPath</code> method on each object.
1432 * This method returns a 0 if the specified <code>Object</code> is equal
1433 * to this one, a negative value if it is less than this one
1434 * a positive value if it is greater than this one.
1436 * @return An integer as described above
1440 public int compareTo(File other)
1443 return path.compareTo (other.path);
1445 return path.compareToIgnoreCase (other.path);
1449 * This method compares the specified <code>Object</code> to this one
1450 * to test for equality. It does this by comparing the canonical path names
1451 * of the files. This method is identical to <code>compareTo(File)</code>
1452 * except that if the <code>Object</code> passed to it is not a
1453 * <code>File</code>, it throws a <code>ClassCastException</code>
1455 * The canonical paths of the files are determined by calling the
1456 * <code>getCanonicalPath</code> method on each object.
1458 * This method returns a 0 if the specified <code>Object</code> is equal
1459 * to this one, a negative value if it is less than this one
1460 * a positive value if it is greater than this one.
1462 * @return An integer as described above
1464 * @exception ClassCastException If the passed <code>Object</code> is
1465 * not a <code>File</code>
1469 public int compareTo(Object obj)
1471 return compareTo((File) obj);
1475 * This native method actually performs the rename.
1477 private native boolean performRenameTo (File dest);
1480 * This method renames the file represented by this object to the path
1481 * of the file represented by the argument <code>File</code>.
1483 * @param dest The <code>File</code> object representing the target name
1485 * @return <code>true</code> if the rename succeeds, <code>false</code>
1488 * @exception SecurityException If write access is not allowed to the
1489 * file by the <code>SecurityMananger</code>.
1491 public synchronized boolean renameTo(File dest)
1493 SecurityManager s = System.getSecurityManager();
1496 s.checkWrite (getPath());
1497 s.checkWrite (dest.getPath());
1499 return performRenameTo (dest);
1503 * This method does the actual setting of the modification time.
1505 private native boolean performSetLastModified(long time);
1508 * This method sets the modification time on the file to the specified
1509 * value. This is specified as the number of seconds since midnight
1510 * on January 1, 1970 GMT.
1512 * @param time The desired modification time.
1514 * @return <code>true</code> if the operation succeeded, <code>false</code>
1517 * @exception IllegalArgumentException If the specified time is negative.
1518 * @exception SecurityException If the <code>SecurityManager</code> will
1519 * not allow this operation.
1523 public boolean setLastModified(long time)
1526 throw new IllegalArgumentException("Negative modification time: " + time);
1529 return performSetLastModified(time);
1532 private void checkWrite()
1534 // Check the SecurityManager
1535 SecurityManager s = System.getSecurityManager();
1541 private void checkRead()
1543 // Check the SecurityManager
1544 SecurityManager s = System.getSecurityManager();
1550 private void checkExec()
1552 // Check the SecurityManager
1553 SecurityManager s = System.getSecurityManager();
1560 * Calling this method requests that the file represented by this object
1561 * be deleted when the virtual machine exits. Note that this request cannot
1562 * be cancelled. Also, it will only be carried out if the virtual machine
1565 * @exception SecurityException If deleting of the file is not allowed
1569 // FIXME: This should use the ShutdownHook API once we implement that.
1570 public void deleteOnExit()
1572 // Check the SecurityManager
1573 SecurityManager sm = System.getSecurityManager();
1575 sm.checkDelete (getPath());
1577 DeleteFileHelper.add(this);
1580 private void writeObject(ObjectOutputStream oos) throws IOException
1582 oos.defaultWriteObject();
1583 oos.writeChar(separatorChar);
1586 private void readObject(ObjectInputStream ois)
1587 throws ClassNotFoundException, IOException
1589 ois.defaultReadObject();
1591 // If the file was from an OS with a different dir separator,
1592 // fixup the path to use the separator on this OS.
1593 char oldSeparatorChar = ois.readChar();
1595 if (oldSeparatorChar != separatorChar)
1596 path = path.replace(oldSeparatorChar, separatorChar);