1 /* File.java -- Class representing a file on disk
2 Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005
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., 59 Temple Place, Suite 330, 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;
47 import gnu.gcj.runtime.FileDeleter;
49 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
50 * "The Java Language Specification", ISBN 0-201-63451-1
51 * Status: Complete to version 1.3.
55 * This class represents a file or directory on a local disk. It provides
56 * facilities for dealing with a variety of systems that use various
57 * types of path separators ("/" versus "\", for example). It also
58 * contains method useful for creating and deleting files and directories.
60 * @author Aaron M. Renn (arenn@urbanophile.com)
61 * @author Tom Tromey (tromey@cygnus.com)
63 public class File implements Serializable, Comparable
65 private static final long serialVersionUID = 301077366599181567L;
67 // QUERY arguments to access function.
68 private final static int READ = 0;
69 private final static int WRITE = 1;
70 private final static int EXISTS = 2;
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);
186 private native boolean performCreate() throws IOException;
189 * This method creates a new file of zero length with the same name as
190 * the path of this <code>File</code> object if an only if that file
191 * does not already exist.
193 * A <code>SecurityManager.checkWrite</code> check is done prior
194 * to performing this action.
196 * @return <code>true</code> if the file was created, <code>false</code> if
197 * the file alread existed.
199 * @exception IOException If an I/O error occurs
200 * @exception SecurityException If the <code>SecurityManager</code> will
201 * not allow this operation to be performed.
205 public boolean createNewFile() throws IOException
208 return performCreate();
212 * This native method handles the actual deleting of the file
214 private native boolean performDelete();
217 * This method deletes the file represented by this object. If this file
218 * is a directory, it must be empty in order for the delete to succeed.
220 * @return <code>true</code> if the file was deleted, <code>false</code>
223 * @exception SecurityException If deleting of the file is not allowed
225 public synchronized boolean delete()
227 SecurityManager s = System.getSecurityManager();
232 return performDelete();
236 * This method tests two <code>File</code> objects for equality by
237 * comparing the path of the specified <code>File</code> against the path
238 * of this object. The two objects are equal if an only if 1) The
239 * argument is not null 2) The argument is a <code>File</code> object and
240 * 3) The path of the <code>File</code>argument is equal to the path
243 * The paths of the files are determined by calling the
244 * <code>getPath()</code>
245 * method on each object.
247 * @return <code>true</code> if the two objects are equal,
248 * <code>false</code> otherwise.
250 public boolean equals(Object obj)
252 if (! (obj instanceof File))
255 File other = (File) obj;
258 return path.equals(other.path);
260 return path.equalsIgnoreCase(other.path);
264 * This method tests whether or not the file represented by the object
265 * actually exists on the filesystem.
267 * @return <code>true</code> if the file exists, <code>false</code>otherwise.
269 * @exception SecurityException If reading of the file is not permitted
271 public boolean exists()
274 return _access (EXISTS);
278 * This method initializes a new <code>File</code> object to represent
279 * a file with the specified path.
281 * @param name The path name of the file
283 public File(String name)
285 path = normalizePath (name);
288 // Remove duplicate and redundant separator characters.
289 private String normalizePath(String p)
291 // On Windows, convert any '/' to '\'. This appears to be the same logic
292 // that Sun's Win32 Java performs.
293 if (separatorChar == '\\')
295 p = p.replace ('/', '\\');
296 // We have to special case the "\c:" prefix.
297 if (p.length() > 2 && p.charAt(0) == '\\' &&
298 ((p.charAt(1) >= 'a' && p.charAt(1) <= 'z') ||
299 (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z')) &&
304 int dupIndex = p.indexOf(dupSeparator);
305 int plen = p.length();
307 // Special case: permit Windows UNC path prefix.
308 if (dupSeparator.equals("\\\\") && dupIndex == 0)
309 dupIndex = p.indexOf(dupSeparator, 1);
313 // Ignore trailing separator (though on Windows "a:\", for
314 // example, is a valid and minimal path).
315 if (plen > 1 && p.charAt (plen - 1) == separatorChar)
317 if (! (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':'))
318 return p.substring (0, plen - 1);
324 StringBuffer newpath = new StringBuffer(plen);
326 while (dupIndex != -1)
328 newpath.append(p.substring(last, dupIndex));
329 // Ignore the duplicate path characters.
330 while (p.charAt(dupIndex) == separatorChar)
333 if (dupIndex == plen)
334 return newpath.toString();
336 newpath.append(separatorChar);
338 dupIndex = p.indexOf(dupSeparator, last);
341 // Again, ignore possible trailing separator (except special cases
342 // like "a:\" on Windows).
344 if (plen > 1 && p.charAt (plen - 1) == separatorChar)
346 if (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':')
353 newpath.append(p.substring(last, end));
355 return newpath.toString();
359 * This method initializes a new <code>File</code> object to represent
360 * a file in the specified named directory. The path name to the file
361 * will be the directory name plus the separator string plus the file
362 * name. If the directory path name ends in the separator string, another
363 * separator string will still be appended.
365 * @param dirPath The path to the directory the file resides in
366 * @param name The name of the file
368 public File(String dirPath, String name)
371 throw new NullPointerException();
374 if (dirPath.length() > 0)
376 // Try to be smart about the number of separator characters.
377 if (dirPath.charAt(dirPath.length() - 1) == separatorChar
378 || name.length() == 0)
379 path = normalizePath(dirPath + name);
381 path = normalizePath(dirPath + separatorChar + name);
385 // If dirPath is empty, use a system dependant
387 // Note that the leading separators in name have
388 // to be chopped off, to prevent them forming
389 // a UNC prefix on Windows.
390 if (separatorChar == '\\' /* TODO use ON_WINDOWS */)
393 while(name.length() > skip
394 && (name.charAt(skip) == separatorChar
395 || name.charAt(skip) == '/'))
399 name = name.substring(skip);
401 path = normalizePath(separatorChar + name);
405 path = normalizePath(name);
409 * This method initializes a new <code>File</code> object to represent
410 * a file in the specified directory. If the <code>directory</code>
411 * argument is <code>null</code>, the file is assumed to be in the
412 * current directory as specified by the <code>user.dir</code> system
415 * @param directory The directory this file resides in
416 * @param name The name of the file
418 public File(File directory, String name)
420 this (directory == null ? null : directory.path, name);
424 * This method initializes a new <code>File</code> object to represent
425 * a file corresponding to the specified <code>file:</code> protocol URI.
427 * @param uri The uri.
432 throw new NullPointerException("uri is null");
434 if (!uri.getScheme().equals("file"))
435 throw new IllegalArgumentException("invalid uri protocol");
437 path = normalizePath(uri.getPath());
441 * This method returns the path of this file as an absolute path name.
442 * If the path name is already absolute, then it is returned. Otherwise
443 * the value returned is the current directory plus the separatory
444 * string plus the path of the file. The current directory is determined
445 * from the <code>user.dir</code> system property.
447 * @return The absolute path of this file
449 public String getAbsolutePath()
453 else if (separatorChar == '\\'
454 && path.length() > 0 && path.charAt (0) == '\\')
456 // On Windows, even if the path starts with a '\\' it is not
457 // really absolute until we prefix the drive specifier from
458 // the current working directory to it.
459 return System.getProperty ("user.dir").substring (0, 2) + path;
461 else if (separatorChar == '\\'
462 && path.length() > 1 && path.charAt (1) == ':'
463 && ((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
464 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')))
466 // On Windows, a process has a current working directory for
467 // each drive and a path like "G:foo\bar" would mean the
468 // absolute path "G:\wombat\foo\bar" if "\wombat" is the
469 // working directory on the G drive.
470 String drvDir = null;
473 drvDir = new File (path.substring (0, 2)).getCanonicalPath();
475 catch (IOException e)
477 drvDir = path.substring (0, 2) + "\\";
480 // Note: this would return "C:\\." for the path "C:.", if "\"
481 // is the working folder on the C drive, but this is
482 // consistent with what Sun's JRE 1.4.1.01 actually returns!
483 if (path.length() > 2)
484 return drvDir + '\\' + path.substring (2, path.length());
489 return System.getProperty ("user.dir") + separatorChar + path;
493 * This method returns a <code>File</code> object representing the
494 * absolute path of this object.
496 * @return A <code>File</code> with the absolute path of the object.
500 public File getAbsoluteFile()
502 return new File(getAbsolutePath());
506 * This method returns a canonical representation of the pathname of
507 * this file. The actual form of the canonical representation is
508 * different. On the GNU system, the canonical form differs from the
509 * absolute form in that all relative file references to "." and ".."
510 * are resolved and removed.
512 * Note that this method, unlike the other methods which return path
513 * names, can throw an IOException. This is because native method
514 * might be required in order to resolve the canonical path
516 * @exception IOException If an error occurs
518 public native String getCanonicalPath() throws IOException;
521 * This method returns a <code>File</code> object representing the
522 * canonical path of this object.
524 * @return A <code>File</code> instance representing the canonical path of
527 * @exception IOException If an error occurs.
531 public File getCanonicalFile() throws IOException
533 return new File(getCanonicalPath());
537 * This method returns the name of the file. This is everything in the
538 * complete path of the file after the last instance of the separator
541 * @return The file name
543 public String getName()
545 int nameSeqIndex = 0;
547 if (separatorChar == '\\' && path.length() > 1)
549 // On Windows, ignore the drive specifier or the leading '\\'
550 // of a UNC network path, if any (a.k.a. the "prefix").
551 if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
552 || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
553 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
554 && path.charAt (1) == ':'))
556 if (path.length() > 2)
564 = (nameSeqIndex > 0 ? path.substring (nameSeqIndex) : path);
566 int last = nameSeq.lastIndexOf (separatorChar);
568 return nameSeq.substring (last + 1);
572 * This method returns a <code>String</code> the represents this file's
573 * parent. <code>null</code> is returned if the file has no parent. The
574 * parent is determined via a simple operation which removes the
576 * @return The parent directory of this file
578 public String getParent()
580 String prefix = null;
581 int nameSeqIndex = 0;
583 // The "prefix", if present, is the leading "/" on UNIX and
584 // either the drive specifier (e.g. "C:") or the leading "\\"
585 // of a UNC network path on Windows.
586 if (separatorChar == '/' && path.charAt (0) == '/')
591 else if (separatorChar == '\\' && path.length() > 1)
593 if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
594 || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
595 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
596 && path.charAt (1) == ':'))
598 prefix = path.substring (0, 2);
603 // According to the JDK docs, the returned parent path is the
604 // portion of the name sequence before the last separator
605 // character, if found, prefixed by the prefix, otherwise null.
606 if (nameSeqIndex < path.length())
608 String nameSeq = path.substring (nameSeqIndex, path.length());
609 int last = nameSeq.lastIndexOf (separatorChar);
612 else if (last == (nameSeq.length() - 1))
613 // Note: The path would not have a trailing separator
614 // except for cases like "C:\" on Windows (see
615 // normalizePath( )), where Sun's JRE 1.4 returns null.
621 return prefix + nameSeq.substring (0, last);
623 return nameSeq.substring (0, last);
626 // Sun's JRE 1.4 returns null if the prefix is the only
627 // component of the path - so "/" gives null on UNIX and
628 // "C:", "\\", etc. return null on Windows.
633 * This method returns a <code>File</code> object representing the parent
636 * @return a <code>File</code> for the parent of this object.
638 * will be returned if this object does not have a parent.
642 public File getParentFile()
644 String parent = getParent();
645 return parent != null ? new File(parent) : null;
649 * Returns the path name that represents this file. May be a relative
650 * or an absolute path name
652 * @return The pathname of this file
654 public String getPath()
660 * This method returns a hash code representing this file. It is the
661 * hash code of the path of this file (as returned by <code>getPath()</code>)
662 * exclusived or-ed with the value 1234321.
664 * @return The hash code for this object
666 public int hashCode()
669 return path.hashCode() ^ 1234321;
671 return path.toLowerCase().hashCode() ^ 1234321;
675 * This method returns true if this object represents an absolute file
676 * path and false if it does not. The definition of an absolute path varies
677 * by system. As an example, on GNU systems, a path is absolute if it starts
680 * @return <code>true</code> if this object represents an absolute
681 * file name, <code>false</code> otherwise.
683 public native boolean isAbsolute();
686 * This method tests whether or not the file represented by this object
687 * is a directory. In order for this method to return <code>true</code>,
688 * the file represented by this object must exist and be a directory.
690 * @return <code>true</code> if this file is a directory, <code>false</code>
693 * @exception SecurityException If reading of the file is not permitted
695 public boolean isDirectory()
698 return _stat (DIRECTORY);
702 * This method tests whether or not the file represented by this object
703 * is a "plain" file. A file is a plain file if and only if it 1) Exists,
704 * 2) Is not a directory or other type of special file.
706 * @return <code>true</code> if this is a plain file, <code>false</code>
709 * @exception SecurityException If reading of the file is not permitted
711 public boolean isFile()
714 return _stat (ISFILE);
718 * This method tests whether or not this file represents a "hidden" file.
719 * On GNU systems, a file is hidden if its name begins with a "."
720 * character. Files with these names are traditionally not shown with
721 * directory listing tools.
723 * @return <code>true</code> if the file is hidden, <code>false</code>
728 public boolean isHidden()
731 return _stat (ISHIDDEN);
735 * This method returns the last modification time of this file. The
736 * time value returned is an abstract value that should not be interpreted
737 * as a specified time value. It is only useful for comparing to other
738 * such time values returned on the same system. In that case, the larger
739 * value indicates a more recent modification time.
741 * If the file does not exist, then a value of 0 is returned.
743 * @return The last modification time of the file
745 * @exception SecurityException If reading of the file is not permitted
747 public long lastModified()
750 return attr (MODIFIED);
754 * This method returns the length of the file represented by this object,
755 * or 0 if the specified file does not exist.
757 * @return The length of the file
759 * @exception SecurityException If reading of the file is not permitted
764 return attr (LENGTH);
768 * This native function actually produces the list of file in this
771 private final native Object[] performList (FilenameFilter filter,
772 FileFilter fileFilter,
776 * This method returns a array of <code>String</code>'s representing the
777 * list of files is then directory represented by this object. If this
778 * object represents a non-directory file or a non-existent file, then
779 * <code>null</code> is returned. The list of files will not contain
780 * any names such as "." or ".." which indicate the current or parent
781 * directory. Also, the names are not guaranteed to be sorted.
783 * In this form of the <code>list()</code> method, a filter is specified
784 * that allows the caller to control which files are returned in the
785 * list. The <code>FilenameFilter</code> specified is called for each
786 * file returned to determine whether or not that file should be included
789 * A <code>SecurityManager</code> check is made prior to reading the
790 * directory. If read access to the directory is denied, an exception
793 * @param filter An object which will identify files to exclude from
794 * the directory listing.
796 * @return An array of files in the directory, or <code>null</code>
797 * if this object does not represent a valid directory.
799 * @exception SecurityException If read access is not allowed to the
800 * directory by the <code>SecurityManager</code>
802 public String[] list(FilenameFilter filter)
805 return (String[]) performList (filter, null, String.class);
809 * This method returns a array of <code>String</code>'s representing the
810 * list of files is then directory represented by this object. If this
811 * object represents a non-directory file or a non-existent file, then
812 * <code>null</code> is returned. The list of files will not contain
813 * any names such as "." or ".." which indicate the current or parent
814 * directory. Also, the names are not guaranteed to be sorted.
816 * A <code>SecurityManager</code> check is made prior to reading the
817 * directory. If read access to the directory is denied, an exception
820 * @return An array of files in the directory, or <code>null</code> if
821 * this object does not represent a valid directory.
823 * @exception SecurityException If read access is not allowed to the
824 * directory by the <code>SecurityManager</code>
826 public String[] list()
829 return (String[]) performList (null, null, String.class);
833 * This method returns an array of <code>File</code> objects representing
834 * all the files in the directory represented by this object. If this
835 * object does not represent a directory, <code>null</code> is returned.
836 * Each of the returned <code>File</code> object is constructed with this
837 * object as its parent.
839 * A <code>SecurityManager</code> check is made prior to reading the
840 * directory. If read access to the directory is denied, an exception
843 * @return An array of <code>File</code> objects for this directory.
845 * @exception SecurityException If the <code>SecurityManager</code> denies
846 * access to this directory.
850 public File[] listFiles()
853 return (File[]) performList (null, null, File.class);
857 * This method returns an array of <code>File</code> objects representing
858 * all the files in the directory represented by this object. If this
859 * object does not represent a directory, <code>null</code> is returned.
860 * Each of the returned <code>File</code> object is constructed with this
861 * object as its parent.
863 * In this form of the <code>listFiles()</code> method, a filter is specified
864 * that allows the caller to control which files are returned in the
865 * list. The <code>FilenameFilter</code> specified is called for each
866 * file returned to determine whether or not that file should be included
869 * A <code>SecurityManager</code> check is made prior to reading the
870 * directory. If read access to the directory is denied, an exception
873 * @return An array of <code>File</code> objects for this directory.
875 * @exception SecurityException If the <code>SecurityManager</code> denies
876 * access to this directory.
880 public File[] listFiles(FilenameFilter filter)
883 return (File[]) performList (filter, null, File.class);
887 * This method returns an array of <code>File</code> objects representing
888 * all the files in the directory represented by this object. If this
889 * object does not represent a directory, <code>null</code> is returned.
890 * Each of the returned <code>File</code> object is constructed with this
891 * object as its parent.
893 * In this form of the <code>listFiles()</code> method, a filter is specified
894 * that allows the caller to control which files are returned in the
895 * list. The <code>FileFilter</code> specified is called for each
896 * file returned to determine whether or not that file should be included
899 * A <code>SecurityManager</code> check is made prior to reading the
900 * directory. If read access to the directory is denied, an exception
903 * @return An array of <code>File</code> objects for this directory.
905 * @exception SecurityException If the <code>SecurityManager</code> denies
906 * access to this directory.
910 public File[] listFiles(FileFilter filter)
913 return (File[]) performList (null, filter, File.class);
917 * This method returns a <code>String</code> that is the path name of the
918 * file as returned by <code>getPath</code>.
920 * @return A <code>String</code> representation of this file
922 public String toString()
928 * @return A <code>URI</code> for this object.
932 String abspath = getAbsolutePath();
935 abspath = abspath + separator;
939 return new URI("file", abspath.replace(separatorChar, '/'), null);
941 catch (URISyntaxException use)
944 throw new RuntimeException(use);
949 * This method returns a <code>URL</code> with the <code>file:</code>
950 * protocol that represents this file. The exact form of this URL is
953 * @return A <code>URL</code> for this object.
955 * @exception MalformedURLException If the URL cannot be created
958 public URL toURL() throws MalformedURLException
960 // On Win32, Sun's JDK returns URLs of the form "file:/c:/foo/bar.txt",
961 // while on UNIX, it returns URLs of the form "file:/foo/bar.txt".
962 if (separatorChar == '\\')
963 return new URL ("file:/" + getAbsolutePath().replace ('\\', '/')
964 + (isDirectory() ? "/" : ""));
966 return new URL ("file:" + getAbsolutePath()
967 + (isDirectory() ? "/" : ""));
971 * This native method actually creates the directory
973 private final native boolean performMkdir();
976 * This method creates a directory for the path represented by this object.
978 * @return <code>true</code> if the directory was created,
979 * <code>false</code> otherwise
981 * @exception SecurityException If write access is not allowed to this file
983 public boolean mkdir()
986 return performMkdir();
989 private static boolean mkdirs (File x)
993 String p = x.getPath();
994 String parent = x.getParent();
1006 * This method creates a directory for the path represented by this file.
1007 * It will also create any intervening parent directories if necessary.
1009 * @return <code>true</code> if the directory was created,
1010 * <code>false</code> otherwise
1012 * @exception SecurityException If write access is not allowed to this file
1014 public boolean mkdirs()
1019 return mkdirs (new File (path));
1022 private static synchronized String nextValue()
1024 return Long.toString(counter++, Character.MAX_RADIX);
1028 * This method creates a temporary file in the specified directory. If
1029 * the directory name is null, then this method uses the system temporary
1030 * directory. The files created are guaranteed not to currently exist and
1031 * the same file name will never be used twice in the same virtual
1033 * The system temporary directory is determined by examinging the
1034 * <code>java.io.tmpdir</code> system property.
1036 * The <code>prefix</code> parameter is a sequence of at least three
1037 * characters that are used as the start of the generated filename. The
1038 * <code>suffix</code> parameter is a sequence of characters that is used
1039 * to terminate the file name. This parameter may be <code>null</code>
1040 * and if it is, the suffix defaults to ".tmp".
1042 * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1043 * method is used to verify that this operation is permitted.
1045 * @param prefix The character prefix to use in generating the path name.
1046 * @param suffix The character suffix to use in generating the path name.
1047 * @param directory The directory to create the file in, or
1048 * <code>null</code> for the default temporary directory
1050 * @exception IllegalArgumentException If the patterns is not valid
1051 * @exception SecurityException If there is no permission to perform
1053 * @exception IOException If an error occurs
1057 public static File createTempFile(String prefix, String suffix,
1061 // Grab the system temp directory if necessary
1062 if (directory == null)
1064 String dirname = tmpdir;
1065 if (dirname == null)
1066 throw new IOException("Cannot determine system temporary directory");
1068 directory = new File(dirname);
1069 if (!directory.exists())
1070 throw new IOException("System temporary directory "
1071 + directory.getName() + " does not exist.");
1072 if (!directory.isDirectory())
1073 throw new IOException("System temporary directory "
1074 + directory.getName()
1075 + " is not really a directory.");
1078 // Check if prefix is at least 3 characters long
1079 if (prefix.length() < 3)
1080 throw new IllegalArgumentException("Prefix too short: " + prefix);
1082 // Set default value of suffix
1086 // Truncation rules.
1087 // `6' is the number of characters we generate.
1088 if (prefix.length() + 6 + suffix.length() > maxPathLen)
1091 if (suffix.charAt(0) == '.')
1093 suffix = suffix.substring(0, suf_len);
1094 if (prefix.length() + 6 + suf_len > maxPathLen)
1095 prefix = prefix.substring(0, maxPathLen - 6 - suf_len);
1100 // How many times should we try? We choose 100.
1101 for (int i = 0; i < 100; ++i)
1104 String t = "ZZZZZZ" + nextValue();
1105 String l = prefix + t.substring(t.length() - 6) + suffix;
1108 f = new File(directory, l);
1109 if (f.createNewFile())
1112 catch (IOException ignored)
1117 throw new IOException ("cannot create temporary file");
1121 * This native method sets the permissions to make the file read only.
1123 private native boolean performSetReadOnly();
1126 * This method sets the file represented by this object to be read only.
1127 * A read only file or directory cannot be modified. Please note that
1128 * GNU systems allow read only files to be deleted if the directory it
1129 * is contained in is writable.
1131 * @return <code>true</code> if the operation succeeded, <code>false</code>
1134 * @exception SecurityException If the <code>SecurityManager</code> does
1135 * not allow this operation.
1139 public boolean setReadOnly()
1141 // Do a security check before trying to do anything else.
1143 return performSetReadOnly();
1146 private static native File[] performListRoots();
1149 * This method returns an array of filesystem roots. Some operating systems
1150 * have volume oriented filesystem. This method provides a mechanism for
1151 * determining which volumes exist. GNU systems use a single hierarchical
1152 * filesystem, so will have only one "/" filesystem root.
1154 * @return An array of <code>File</code> objects for each filesystem root
1159 public static File[] listRoots()
1161 File[] roots = performListRoots();
1163 SecurityManager s = System.getSecurityManager();
1166 // Only return roots to which the security manager permits read access.
1167 int count = roots.length;
1168 for (int i = 0; i < roots.length; i++)
1172 s.checkRead (roots[i].path);
1174 catch (SecurityException sx)
1180 if (count != roots.length)
1182 File[] newRoots = new File[count];
1184 for (int i=0; i < roots.length; i++)
1186 if (roots[i] != null)
1187 newRoots[k++] = roots[i];
1196 * This method creates a temporary file in the system temporary directory.
1197 * The files created are guaranteed not to currently exist and the same file
1198 * name will never be used twice in the same virtual machine instance. The
1199 * system temporary directory is determined by examinging the
1200 * <code>java.io.tmpdir</code> system property.
1202 * The <code>prefix</code> parameter is a sequence of at least three
1203 * characters that are used as the start of the generated filename. The
1204 * <code>suffix</code> parameter is a sequence of characters that is used
1205 * to terminate the file name. This parameter may be <code>null</code>
1206 * and if it is, the suffix defaults to ".tmp".
1208 * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1209 * method is used to verify that this operation is permitted.
1211 * This method is identical to calling
1212 * <code>createTempFile(prefix, suffix, null)</code>.
1214 * @param prefix The character prefix to use in generating the path name.
1215 * @param suffix The character suffix to use in generating the path name.
1217 * @exception IllegalArgumentException If the prefix or suffix are not valid.
1218 * @exception SecurityException If there is no permission to perform
1220 * @exception IOException If an error occurs
1222 public static File createTempFile(String prefix, String suffix)
1225 return createTempFile(prefix, suffix, null);
1229 * This method compares the specified <code>File</code> to this one
1230 * to test for equality. It does this by comparing the canonical path names
1233 * The canonical paths of the files are determined by calling the
1234 * <code>getCanonicalPath</code> method on each object.
1236 * This method returns a 0 if the specified <code>Object</code> is equal
1237 * to this one, a negative value if it is less than this one
1238 * a positive value if it is greater than this one.
1240 * @return An integer as described above
1244 public int compareTo(File other)
1247 return path.compareTo (other.path);
1249 return path.compareToIgnoreCase (other.path);
1253 * This method compares the specified <code>Object</code> to this one
1254 * to test for equality. It does this by comparing the canonical path names
1255 * of the files. This method is identical to <code>compareTo(File)</code>
1256 * except that if the <code>Object</code> passed to it is not a
1257 * <code>File</code>, it throws a <code>ClassCastException</code>
1259 * The canonical paths of the files are determined by calling the
1260 * <code>getCanonicalPath</code> method on each object.
1262 * This method returns a 0 if the specified <code>Object</code> is equal
1263 * to this one, a negative value if it is less than this one
1264 * a positive value if it is greater than this one.
1266 * @return An integer as described above
1268 * @exception ClassCastException If the passed <code>Object</code> is
1269 * not a <code>File</code>
1273 public int compareTo(Object obj)
1275 return compareTo((File) obj);
1279 * This native method actually performs the rename.
1281 private native boolean performRenameTo (File dest);
1284 * This method renames the file represented by this object to the path
1285 * of the file represented by the argument <code>File</code>.
1287 * @param dest The <code>File</code> object representing the target name
1289 * @return <code>true</code> if the rename succeeds, <code>false</code>
1292 * @exception SecurityException If write access is not allowed to the
1293 * file by the <code>SecurityMananger</code>.
1295 public synchronized boolean renameTo(File dest)
1297 SecurityManager s = System.getSecurityManager();
1298 String sname = getName();
1299 String dname = dest.getName();
1302 s.checkWrite (sname);
1303 s.checkWrite (dname);
1305 return performRenameTo (dest);
1309 * This method does the actual setting of the modification time.
1311 private native boolean performSetLastModified(long time);
1314 * This method sets the modification time on the file to the specified
1315 * value. This is specified as the number of seconds since midnight
1316 * on January 1, 1970 GMT.
1318 * @param time The desired modification time.
1320 * @return <code>true</code> if the operation succeeded, <code>false</code>
1323 * @exception IllegalArgumentException If the specified time is negative.
1324 * @exception SecurityException If the <code>SecurityManager</code> will
1325 * not allow this operation.
1329 public boolean setLastModified(long time)
1332 throw new IllegalArgumentException("Negative modification time: " + time);
1335 return performSetLastModified(time);
1338 private void checkWrite()
1340 // Check the SecurityManager
1341 SecurityManager s = System.getSecurityManager();
1347 private void checkRead()
1349 // Check the SecurityManager
1350 SecurityManager s = System.getSecurityManager();
1357 * Calling this method requests that the file represented by this object
1358 * be deleted when the virtual machine exits. Note that this request cannot
1359 * be cancelled. Also, it will only be carried out if the virtual machine
1362 * @exception SecurityException If deleting of the file is not allowed
1366 // FIXME: This should use the ShutdownHook API once we implement that.
1367 public void deleteOnExit()
1369 // Check the SecurityManager
1370 SecurityManager sm = System.getSecurityManager();
1372 sm.checkDelete (getName());
1374 FileDeleter.add (this);
1377 private void writeObject(ObjectOutputStream oos) throws IOException
1379 oos.defaultWriteObject();
1380 oos.writeChar(separatorChar);
1383 private void readObject(ObjectInputStream ois)
1384 throws ClassNotFoundException, IOException
1386 ois.defaultReadObject();
1388 // If the file was from an OS with a different dir separator,
1389 // fixup the path to use the separator on this OS.
1390 char oldSeparatorChar = ois.readChar();
1392 if (oldSeparatorChar != separatorChar)
1393 path = path.replace(oldSeparatorChar, separatorChar);