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 gnu.classpath.SystemProperties;
44 import java.net.MalformedURLException;
46 import java.net.URISyntaxException;
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<File>
65 private static final long serialVersionUID = 301077366599181567L;
68 * This is the path separator string for the current host. This field
69 * contains the value of the <code>file.separator</code> system property.
70 * An example separator string would be "/" on the GNU system.
72 public static final String separator = SystemProperties.getProperty("file.separator");
73 private static final String dupSeparator = separator + separator;
76 * This is the first character of the file separator string. On many
77 * hosts (for example, on the GNU system), this represents the entire
78 * separator string. The complete separator string is obtained from the
79 * <code>file.separator</code>system property.
81 public static final char separatorChar = separator.charAt(0);
84 * This is the string that is used to separate the host name from the
85 * path name in paths that include the host name. It is the value of
86 * the <code>path.separator</code> system property.
88 public static final String pathSeparator
89 = SystemProperties.getProperty("path.separator");
92 * This is the first character of the string used to separate the host name
93 * from the path name in paths that include a host. The separator string
94 * is taken from the <code>path.separator</code> system property.
96 public static final char pathSeparatorChar = pathSeparator.charAt(0);
99 * This is the path to the file set when the object is created. It
100 * may be an absolute or relative path name.
106 * The time (millisecond), when the last temporary file was created.
108 private static long last_tmp;
111 * The number of files, created during the current millisecond.
113 private static int n_created;
116 * This method tests whether or not the current thread is allowed to
117 * to read the file pointed to by this object. This will be true if and
118 * and only if 1) the file exists and 2) the <code>SecurityManager</code>
119 * (if any) allows access to the file via it's <code>checkRead</code>
120 * method 3) the file is readable.
122 * @return <code>true</code> if reading is allowed,
123 * <code>false</code> otherwise
125 * @exception SecurityException If the <code>SecurityManager</code>
126 * does not allow access to the file
128 public boolean canRead()
130 // Test for existence. This also does the SecurityManager check
134 return VMFile.canRead(path);
138 * This method test whether or not the current thread is allowed to
139 * write to this object. This will be true if and only if 1) The
140 * <code>SecurityManager</code> (if any) allows write access to the
141 * file and 2) The file exists and 3) The file is writable. To determine
142 * whether or not a non-existent file can be created, check the parent
143 * directory for write access.
145 * @return <code>true</code> if writing is allowed, <code>false</code>
148 * @exception SecurityException If the <code>SecurityManager</code>
149 * does not allow access to the file
151 public boolean canWrite()
153 // First do a SecurityCheck before doing anything else.
156 // Test for existence. This is required by the spec
157 if (! VMFile.exists(path))
160 if (VMFile.isDirectory(path))
161 return VMFile.canWriteDirectory(this);
163 return VMFile.canWrite(path);
167 * This method creates a new file of zero length with the same name as
168 * the path of this <code>File</code> object if an only if that file
169 * does not already exist.
171 * A <code>SecurityManager.checkWrite</code> check is done prior
172 * to performing this action.
174 * @return <code>true</code> if the file was created, <code>false</code> if
175 * the file alread existed.
177 * @exception IOException If an I/O error occurs
178 * @exception SecurityException If the <code>SecurityManager</code> will
179 * not allow this operation to be performed.
183 public boolean createNewFile() throws IOException
186 return VMFile.create(path);
189 * This method deletes the file represented by this object. If this file
190 * is a directory, it must be empty in order for the delete to succeed.
192 * @return <code>true</code> if the file was deleted, <code>false</code>
195 * @exception SecurityException If deleting of the file is not allowed
197 public synchronized boolean delete()
199 SecurityManager s = System.getSecurityManager();
204 return VMFile.delete(path);
208 * This method tests two <code>File</code> objects for equality by
209 * comparing the path of the specified <code>File</code> against the path
210 * of this object. The two objects are equal if an only if 1) The
211 * argument is not null 2) The argument is a <code>File</code> object and
212 * 3) The path of the <code>File</code>argument is equal to the path
215 * The paths of the files are determined by calling the
216 * <code>getPath()</code>
217 * method on each object.
219 * @return <code>true</code> if the two objects are equal,
220 * <code>false</code> otherwise.
222 public boolean equals(Object obj)
224 if (! (obj instanceof File))
227 File other = (File) obj;
229 if (VMFile.IS_CASE_SENSITIVE)
230 return path.equals(other.path);
232 return path.equalsIgnoreCase(other.path);
236 * This method tests whether or not the file represented by the object
237 * actually exists on the filesystem.
239 * @return <code>true</code> if the file exists, <code>false</code>otherwise.
241 * @exception SecurityException If reading of the file is not permitted
243 public boolean exists()
246 return VMFile.exists(path);
250 * This method initializes a new <code>File</code> object to represent
251 * a file with the specified path.
253 * @param name The path name of the file
255 public File(String name)
257 path = normalizePath (name);
260 // Remove duplicate and redundant separator characters.
261 private String normalizePath(String p)
263 // On Windows, convert any '/' to '\'. This appears to be the same logic
264 // that Sun's Win32 Java performs.
265 if (separatorChar == '\\')
267 p = p.replace ('/', '\\');
268 // We have to special case the "\c:" prefix.
269 if (p.length() > 2 && p.charAt(0) == '\\' &&
270 ((p.charAt(1) >= 'a' && p.charAt(1) <= 'z') ||
271 (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z')) &&
276 int dupIndex = p.indexOf(dupSeparator);
277 int plen = p.length();
279 // Special case: permit Windows UNC path prefix.
280 if (dupSeparator.equals("\\\\") && dupIndex == 0)
281 dupIndex = p.indexOf(dupSeparator, 1);
285 // Ignore trailing separator (though on Windows "a:\", for
286 // example, is a valid and minimal path).
287 if (plen > 1 && p.charAt (plen - 1) == separatorChar)
289 if (! (separatorChar == '\\' && ((plen == 3 && p.charAt(1) == ':')
290 || (plen == 2 && p.charAt(0) == separatorChar))))
291 return p.substring (0, plen - 1);
297 StringBuffer newpath = new StringBuffer(plen);
299 while (dupIndex != -1)
301 newpath.append(p.substring(last, dupIndex));
302 // Ignore the duplicate path characters.
303 while (p.charAt(dupIndex) == separatorChar)
306 if (dupIndex == plen)
308 if ((separatorChar == '\\'
309 && newpath.length() == 2
310 && newpath.charAt(1) == ':')
311 || (separatorChar != '\\' && newpath.length() == 0))
313 newpath.append(separatorChar);
315 return newpath.toString();
318 newpath.append(separatorChar);
320 dupIndex = p.indexOf(dupSeparator, last);
323 // Again, ignore possible trailing separator (except special cases
324 // like "a:\" on Windows).
326 if (plen > 1 && p.charAt (plen - 1) == separatorChar)
328 if (separatorChar == '\\'
329 && ((plen == 3 && p.charAt(1) == ':')
330 || (plen == 2 && p.charAt(0) == separatorChar)))
337 newpath.append(p.substring(last, end));
339 return newpath.toString();
343 * This method initializes a new <code>File</code> object to represent
344 * a file in the specified named directory. The path name to the file
345 * will be the directory name plus the separator string plus the file
346 * name. If the directory path name ends in the separator string, another
347 * separator string will still be appended.
349 * @param dirPath The path to the directory the file resides in
350 * @param name The name of the file
352 public File(String dirPath, String name)
355 throw new NullPointerException();
358 if (dirPath.length() > 0)
360 // Try to be smart about the number of separator characters.
361 if (dirPath.charAt(dirPath.length() - 1) == separatorChar
362 || name.length() == 0)
363 path = normalizePath(dirPath + name);
365 path = normalizePath(dirPath + separatorChar + name);
369 // If dirPath is empty, use a system dependant
371 // Note that the leading separators in name have
372 // to be chopped off, to prevent them forming
373 // a UNC prefix on Windows.
374 if (separatorChar == '\\' /* TODO use ON_WINDOWS */)
377 while(name.length() > skip
378 && (name.charAt(skip) == separatorChar
379 || name.charAt(skip) == '/'))
383 name = name.substring(skip);
385 path = normalizePath(separatorChar + name);
389 path = normalizePath(name);
393 * This method initializes a new <code>File</code> object to represent
394 * a file in the specified directory. If the <code>directory</code>
395 * argument is <code>null</code>, the file is assumed to be in the
396 * current directory as specified by the <code>user.dir</code> system
399 * @param directory The directory this file resides in
400 * @param name The name of the file
402 public File(File directory, String name)
404 this (directory == null ? null : directory.path, name);
408 * This method initializes a new <code>File</code> object to represent
409 * a file corresponding to the specified <code>file:</code> protocol URI.
412 * @throws IllegalArgumentException if the URI is not hierarchical
417 throw new NullPointerException("uri is null");
419 if (!uri.getScheme().equals("file"))
420 throw new IllegalArgumentException("invalid uri protocol");
422 String name = uri.getPath();
424 throw new IllegalArgumentException("URI \"" + uri
425 + "\" is not hierarchical");
426 path = normalizePath(name);
430 * This method returns the path of this file as an absolute path name.
431 * If the path name is already absolute, then it is returned. Otherwise
432 * the value returned is the current directory plus the separatory
433 * string plus the path of the file. The current directory is determined
434 * from the <code>user.dir</code> system property.
436 * @return The absolute path of this file
438 public String getAbsolutePath()
443 return VMFile.getAbsolutePath(path);
447 * This method returns a <code>File</code> object representing the
448 * absolute path of this object.
450 * @return A <code>File</code> with the absolute path of the object.
454 public File getAbsoluteFile()
456 return new File(getAbsolutePath());
460 * This method returns a canonical representation of the pathname of
461 * this file. The actual form of the canonical representation is
462 * system-dependent. On the GNU system, conversion to canonical
463 * form involves the removal of redundant separators, references to
464 * "." and "..", and symbolic links.
466 * Note that this method, unlike the other methods which return path
467 * names, can throw an IOException. This is because native method
468 * might be required in order to resolve the canonical path
470 * @exception IOException If an error occurs
472 public String getCanonicalPath() throws IOException
474 // On Windows, getAbsolutePath might end up calling us, so we
475 // have to special case that call to avoid infinite recursion.
476 if (separatorChar == '\\' && path.length() == 2 &&
477 ((path.charAt(0) >= 'a' && path.charAt(0) <= 'z') ||
478 (path.charAt(0) >= 'A' && path.charAt(0) <= 'Z')) &&
479 path.charAt(1) == ':')
481 return VMFile.toCanonicalForm(path);
483 // Call getAbsolutePath first to make sure that we do the
484 // current directory handling, because the native code
485 // may have a different idea of the current directory.
486 return VMFile.toCanonicalForm(getAbsolutePath());
490 * This method returns a <code>File</code> object representing the
491 * canonical path of this object.
493 * @return A <code>File</code> instance representing the canonical path of
496 * @exception IOException If an error occurs.
500 public File getCanonicalFile() throws IOException
502 return new File(getCanonicalPath());
506 * This method returns the name of the file. This is everything in the
507 * complete path of the file after the last instance of the separator
510 * @return The file name
512 public String getName()
514 return VMFile.getName(path);
518 * This method returns a <code>String</code> the represents this file's
519 * parent. <code>null</code> is returned if the file has no parent. The
520 * parent is determined via a simple operation which removes the name
521 * after the last file separator character, as determined by the platform.
523 * @return The parent directory of this file
525 public String getParent()
527 String prefix = null;
528 int nameSeqIndex = 0;
533 // The "prefix", if present, is the leading "/" on UNIX and
534 // either the drive specifier (e.g. "C:") or the leading "\\"
535 // of a UNC network path on Windows.
536 if (separatorChar == '/' && path.charAt (0) == '/')
541 else if (separatorChar == '\\' && path.length() > 1)
543 if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
544 || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
545 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
546 && path.charAt (1) == ':'))
548 prefix = path.substring (0, 2);
553 // According to the JDK docs, the returned parent path is the
554 // portion of the name sequence before the last separator
555 // character, if found, prefixed by the prefix, otherwise null.
556 if (nameSeqIndex < path.length())
558 String nameSeq = path.substring (nameSeqIndex, path.length());
559 int last = nameSeq.lastIndexOf (separatorChar);
562 else if (last == (nameSeq.length() - 1))
563 // Note: The path would not have a trailing separator
564 // except for cases like "C:\" on Windows (see
565 // normalizePath( )), where Sun's JRE 1.4 returns null.
571 return prefix + nameSeq.substring (0, last);
573 return nameSeq.substring (0, last);
576 // Sun's JRE 1.4 returns null if the prefix is the only
577 // component of the path - so "/" gives null on UNIX and
578 // "C:", "\\", etc. return null on Windows.
583 * This method returns a <code>File</code> object representing the parent
586 * @return a <code>File</code> for the parent of this object.
588 * will be returned if this object does not have a parent.
592 public File getParentFile()
594 String parent = getParent();
595 return parent != null ? new File(parent) : null;
599 * Returns the path name that represents this file. May be a relative
600 * or an absolute path name
602 * @return The pathname of this file
604 public String getPath()
610 * This method returns a hash code representing this file. It is the
611 * hash code of the path of this file (as returned by <code>getPath()</code>)
612 * exclusived or-ed with the value 1234321.
614 * @return The hash code for this object
616 public int hashCode()
618 if (VMFile.IS_CASE_SENSITIVE)
619 return path.hashCode() ^ 1234321;
621 return path.toLowerCase().hashCode() ^ 1234321;
625 * This method returns true if this object represents an absolute file
626 * path and false if it does not. The definition of an absolute path varies
627 * by system. As an example, on GNU systems, a path is absolute if it starts
630 * @return <code>true</code> if this object represents an absolute
631 * file name, <code>false</code> otherwise.
633 public boolean isAbsolute()
635 return VMFile.isAbsolute(path);
639 * This method tests whether or not the file represented by this object
640 * is a directory. In order for this method to return <code>true</code>,
641 * the file represented by this object must exist and be a directory.
643 * @return <code>true</code> if this file is a directory, <code>false</code>
646 * @exception SecurityException If reading of the file is not permitted
648 public boolean isDirectory()
651 return VMFile.isDirectory(path);
655 * This method tests whether or not the file represented by this object
656 * is a "plain" file. A file is a plain file if and only if it 1) Exists,
657 * 2) Is not a directory or other type of special file.
659 * @return <code>true</code> if this is a plain file, <code>false</code>
662 * @exception SecurityException If reading of the file is not permitted
664 public boolean isFile()
667 return VMFile.isFile(path);
671 * This method tests whether or not this file represents a "hidden" file.
672 * On GNU systems, a file is hidden if its name begins with a "."
673 * character. Files with these names are traditionally not shown with
674 * directory listing tools.
676 * @return <code>true</code> if the file is hidden, <code>false</code>
681 public boolean isHidden()
683 return VMFile.isHidden(path);
687 * This method returns the last modification time of this file. The
688 * time value returned is an abstract value that should not be interpreted
689 * as a specified time value. It is only useful for comparing to other
690 * such time values returned on the same system. In that case, the larger
691 * value indicates a more recent modification time.
693 * If the file does not exist, then a value of 0 is returned.
695 * @return The last modification time of the file
697 * @exception SecurityException If reading of the file is not permitted
699 public long lastModified()
702 return VMFile.lastModified(path);
706 * This method returns the length of the file represented by this object,
707 * or 0 if the specified file does not exist.
709 * @return The length of the file
711 * @exception SecurityException If reading of the file is not permitted
716 return VMFile.length(path);
720 * This method returns a array of <code>String</code>'s representing the
721 * list of files is then directory represented by this object. If this
722 * object represents a non-directory file or a non-existent file, then
723 * <code>null</code> is returned. The list of files will not contain
724 * any names such as "." or ".." which indicate the current or parent
725 * directory. Also, the names are not guaranteed to be sorted.
727 * In this form of the <code>list()</code> method, a filter is specified
728 * that allows the caller to control which files are returned in the
729 * list. The <code>FilenameFilter</code> specified is called for each
730 * file returned to determine whether or not that file should be included
733 * A <code>SecurityManager</code> check is made prior to reading the
734 * directory. If read access to the directory is denied, an exception
737 * @param filter An object which will identify files to exclude from
738 * the directory listing.
740 * @return An array of files in the directory, or <code>null</code>
741 * if this object does not represent a valid directory.
743 * @exception SecurityException If read access is not allowed to the
744 * directory by the <code>SecurityManager</code>
746 public String[] list(FilenameFilter filter)
750 if (!exists() || !isDirectory())
753 // Get the list of files
754 String files[] = VMFile.list(path);
756 // Check if an error occured in listInternal().
757 // This is an unreadable directory, pretend there is nothing inside.
759 return new String[0];
766 for (int i = 0; i < files.length; i++)
768 if (filter.accept(this, files[i]))
774 String[] retfiles = new String[count];
776 for (int i = 0; i < files.length; i++)
777 if (files[i] != null)
778 retfiles[count++] = files[i];
784 * This method returns a array of <code>String</code>'s representing the
785 * list of files is then directory represented by this object. If this
786 * object represents a non-directory file or a non-existent file, then
787 * <code>null</code> is returned. The list of files will not contain
788 * any names such as "." or ".." which indicate the current or parent
789 * directory. Also, the names are not guaranteed to be sorted.
791 * A <code>SecurityManager</code> check is made prior to reading the
792 * directory. If read access to the directory is denied, an exception
795 * @return An array of files in the directory, or <code>null</code> if
796 * this object does not represent a valid directory.
798 * @exception SecurityException If read access is not allowed to the
799 * directory by the <code>SecurityManager</code>
801 public String[] list()
807 * This method returns an array of <code>File</code> objects representing
808 * all the files in the directory represented by this object. If this
809 * object does not represent a directory, <code>null</code> is returned.
810 * Each of the returned <code>File</code> object is constructed with this
811 * object as its parent.
813 * A <code>SecurityManager</code> check is made prior to reading the
814 * directory. If read access to the directory is denied, an exception
817 * @return An array of <code>File</code> objects for this directory.
819 * @exception SecurityException If the <code>SecurityManager</code> denies
820 * access to this directory.
824 public File[] listFiles()
826 return listFiles((FilenameFilter) null);
830 * This method returns an array of <code>File</code> objects representing
831 * all the files in the directory represented by this object. If this
832 * object does not represent a directory, <code>null</code> is returned.
833 * Each of the returned <code>File</code> object is constructed with this
834 * object as its parent.
836 * In this form of the <code>listFiles()</code> method, a filter is specified
837 * that allows the caller to control which files are returned in the
838 * list. The <code>FilenameFilter</code> specified is called for each
839 * file returned to determine whether or not that file should be included
842 * A <code>SecurityManager</code> check is made prior to reading the
843 * directory. If read access to the directory is denied, an exception
846 * @return An array of <code>File</code> objects for this directory.
848 * @exception SecurityException If the <code>SecurityManager</code> denies
849 * access to this directory.
853 public File[] listFiles(FilenameFilter filter)
855 String[] filelist = list(filter);
857 if (filelist == null)
860 File[] fobjlist = new File [filelist.length];
862 for (int i = 0; i < filelist.length; i++)
863 fobjlist [i] = new File(this, filelist [i]);
869 * This method returns an array of <code>File</code> objects representing
870 * all the files in the directory represented by this object. If this
871 * object does not represent a directory, <code>null</code> is returned.
872 * Each of the returned <code>File</code> object is constructed with this
873 * object as its parent.
875 * In this form of the <code>listFiles()</code> method, a filter is specified
876 * that allows the caller to control which files are returned in the
877 * list. The <code>FileFilter</code> specified is called for each
878 * file returned to determine whether or not that file should be included
881 * A <code>SecurityManager</code> check is made prior to reading the
882 * directory. If read access to the directory is denied, an exception
885 * @return An array of <code>File</code> objects for this directory.
887 * @exception SecurityException If the <code>SecurityManager</code> denies
888 * access to this directory.
892 public File[] listFiles(FileFilter filter)
894 File[] fobjlist = listFiles((FilenameFilter) null);
896 if (fobjlist == null)
903 for (int i = 0; i < fobjlist.length; i++)
904 if (filter.accept(fobjlist[i]) == true)
907 File[] final_list = new File[count];
909 for (int i = 0; i < fobjlist.length; i++)
910 if (filter.accept(fobjlist[i]) == true)
912 final_list[count] = fobjlist[i];
920 * This method returns a <code>String</code> that is the path name of the
921 * file as returned by <code>getPath</code>.
923 * @return A <code>String</code> representation of this file
925 public String toString()
931 * @return A <code>URI</code> for this object.
935 String abspath = getAbsolutePath();
937 if (isDirectory() || path.equals(""))
938 abspath = abspath + separatorChar;
940 if (separatorChar == '\\')
941 abspath = separatorChar + abspath;
945 return new URI("file", null, null, -1,
946 abspath.replace(separatorChar, '/'),
949 catch (URISyntaxException use)
952 throw (InternalError) new InternalError("Unconvertible file: "
953 + this).initCause(use);
958 * This method returns a <code>URL</code> with the <code>file:</code>
959 * protocol that represents this file. The exact form of this URL is
962 * @return A <code>URL</code> for this object.
964 * @exception MalformedURLException If the URL cannot be created
967 public URL toURL() throws MalformedURLException
969 return VMFile.toURL(this);
974 * This method creates a directory for the path represented by this object.
976 * @return <code>true</code> if the directory was created,
977 * <code>false</code> otherwise
979 * @exception SecurityException If write access is not allowed to this file
981 public boolean mkdir()
984 return VMFile.mkdir(path);
988 * This method creates a directory for the path represented by this file.
989 * It will also create any intervening parent directories if necessary.
991 * @return <code>true</code> if the directory was created,
992 * <code>false</code> otherwise
994 * @exception SecurityException If write access is not allowed to this file
996 public boolean mkdirs()
998 String parent = getParent();
1004 File f = new File(parent);
1007 boolean rc = f.mkdirs();
1016 * This method creates a temporary file in the specified directory. If
1017 * the directory name is null, then this method uses the system temporary
1018 * directory. The files created are guaranteed not to currently exist and
1019 * the same file name will never be used twice in the same virtual
1021 * The system temporary directory is determined by examinging the
1022 * <code>java.io.tmpdir</code> system property.
1024 * The <code>prefix</code> parameter is a sequence of at least three
1025 * characters that are used as the start of the generated filename. The
1026 * <code>suffix</code> parameter is a sequence of characters that is used
1027 * to terminate the file name. This parameter may be <code>null</code>
1028 * and if it is, the suffix defaults to ".tmp".
1030 * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1031 * method is used to verify that this operation is permitted.
1033 * @param prefix The character prefix to use in generating the path name.
1034 * @param suffix The character suffix to use in generating the path name.
1035 * @param directory The directory to create the file in, or
1036 * <code>null</code> for the default temporary directory
1038 * @exception IllegalArgumentException If the patterns is not valid
1039 * @exception SecurityException If there is no permission to perform
1041 * @exception IOException If an error occurs
1045 public static synchronized File createTempFile(String prefix, String suffix,
1049 // Grab the system temp directory if necessary
1050 if (directory == null)
1052 String dirname = System.getProperty("java.io.tmpdir");
1053 if (dirname == null)
1054 throw new IOException("Cannot determine system temporary directory");
1056 directory = new File(dirname);
1057 if (! VMFile.exists(directory.path))
1058 throw new IOException("System temporary directory "
1059 + directory.getName() + " does not exist.");
1060 if (! VMFile.isDirectory(directory.path))
1061 throw new IOException("System temporary directory "
1062 + directory.getName()
1063 + " is not really a directory.");
1066 // Check if prefix is at least 3 characters long
1067 if (prefix.length() < 3)
1068 throw new IllegalArgumentException("Prefix too short: " + prefix);
1070 // Set default value of suffix
1074 // Now identify a file name and make sure it doesn't exist.
1076 if (!VMFile.IS_DOS_8_3)
1080 long now = System.currentTimeMillis();
1083 // The last temporary file was created more than 1 ms ago.
1090 String name = Long.toHexString(now);
1092 name += '_'+Integer.toHexString(n_created);
1093 String filename = prefix + name + suffix;
1094 file = new File(directory, filename);
1096 while (VMFile.exists(file.path));
1100 // make sure prefix is not longer than 7 characters
1101 if (prefix.length() >= 8)
1102 throw new IllegalArgumentException("Prefix too long: " + prefix + "(valid length 3..7)");
1104 long mask = 0x000000ffffFFFFL >> (prefix.length() * 4);
1107 int n = (int) (System.currentTimeMillis() & mask);
1108 String filename = prefix + java.lang.Integer.toHexString(n) + suffix;
1109 file = new File(directory, filename);
1111 while (VMFile.exists(file.path));
1114 // Verify that we are allowed to create this file
1115 SecurityManager sm = System.getSecurityManager();
1117 sm.checkWrite(file.getAbsolutePath());
1119 // Now create the file and return our file object
1120 // XXX - FIXME race condition.
1121 VMFile.create(file.getAbsolutePath());
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.
1144 // Test for existence.
1145 if (! VMFile.exists(path))
1148 return VMFile.setReadOnly(path);
1152 * This method returns an array of filesystem roots. Some operating systems
1153 * have volume oriented filesystem. This method provides a mechanism for
1154 * determining which volumes exist. GNU systems use a single hierarchical
1155 * filesystem, so will have only one "/" filesystem root.
1157 * @return An array of <code>File</code> objects for each filesystem root
1162 public static File[] listRoots()
1164 File[] roots = VMFile.listRoots();
1166 SecurityManager s = System.getSecurityManager();
1169 // Only return roots to which the security manager permits read access.
1170 int count = roots.length;
1171 for (int i = 0; i < roots.length; i++)
1175 s.checkRead (roots[i].path);
1177 catch (SecurityException sx)
1183 if (count != roots.length)
1185 File[] newRoots = new File[count];
1187 for (int i = 0; i < roots.length; i++)
1189 if (roots[i] != null)
1190 newRoots[k++] = roots[i];
1199 * This method creates a temporary file in the system temporary directory.
1200 * The files created are guaranteed not to currently exist and the same file
1201 * name will never be used twice in the same virtual machine instance. The
1202 * system temporary directory is determined by examinging the
1203 * <code>java.io.tmpdir</code> system property.
1205 * The <code>prefix</code> parameter is a sequence of at least three
1206 * characters that are used as the start of the generated filename. The
1207 * <code>suffix</code> parameter is a sequence of characters that is used
1208 * to terminate the file name. This parameter may be <code>null</code>
1209 * and if it is, the suffix defaults to ".tmp".
1211 * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1212 * method is used to verify that this operation is permitted.
1214 * This method is identical to calling
1215 * <code>createTempFile(prefix, suffix, null)</code>.
1217 * @param prefix The character prefix to use in generating the path name.
1218 * @param suffix The character suffix to use in generating the path name.
1220 * @exception IllegalArgumentException If the prefix or suffix are not valid.
1221 * @exception SecurityException If there is no permission to perform
1223 * @exception IOException If an error occurs
1225 public static File createTempFile(String prefix, String suffix)
1228 return createTempFile(prefix, suffix, null);
1232 * This method compares the specified <code>File</code> to this one
1233 * to test for equality. It does this by comparing the canonical path names
1236 * The canonical paths of the files are determined by calling the
1237 * <code>getCanonicalPath</code> method on each object.
1239 * This method returns a 0 if the specified <code>Object</code> is equal
1240 * to this one, a negative value if it is less than this one
1241 * a positive value if it is greater than this one.
1243 * @return An integer as described above
1247 public int compareTo(File other)
1249 if (VMFile.IS_CASE_SENSITIVE)
1250 return path.compareTo (other.path);
1252 return path.compareToIgnoreCase (other.path);
1256 * This method renames the file represented by this object to the path
1257 * of the file represented by the argument <code>File</code>.
1259 * @param dest The <code>File</code> object representing the target name
1261 * @return <code>true</code> if the rename succeeds, <code>false</code>
1264 * @exception SecurityException If write access is not allowed to the
1265 * file by the <code>SecurityMananger</code>.
1267 public synchronized boolean renameTo(File dest)
1271 // Call our native rename method
1272 return VMFile.renameTo(path, dest.path);
1276 * This method sets the modification time on the file to the specified
1277 * value. This is specified as the number of seconds since midnight
1278 * on January 1, 1970 GMT.
1280 * @param time The desired modification time.
1282 * @return <code>true</code> if the operation succeeded, <code>false</code>
1285 * @exception IllegalArgumentException If the specified time is negative.
1286 * @exception SecurityException If the <code>SecurityManager</code> will
1287 * not allow this operation.
1291 public boolean setLastModified(long time)
1294 throw new IllegalArgumentException("Negative modification time: " + time);
1297 return VMFile.setLastModified(path, time);
1300 private void checkWrite()
1302 // Check the SecurityManager
1303 SecurityManager s = System.getSecurityManager();
1309 private void checkRead()
1311 // Check the SecurityManager
1312 SecurityManager s = System.getSecurityManager();
1319 * Calling this method requests that the file represented by this object
1320 * be deleted when the virtual machine exits. Note that this request cannot
1321 * be cancelled. Also, it will only be carried out if the virtual machine
1324 * @exception SecurityException If deleting of the file is not allowed
1328 public void deleteOnExit()
1330 // Check the SecurityManager
1331 SecurityManager sm = System.getSecurityManager();
1333 sm.checkDelete(path);
1335 DeleteFileHelper.add(this);
1338 private void writeObject(ObjectOutputStream oos) throws IOException
1340 oos.defaultWriteObject();
1341 oos.writeChar(separatorChar);
1344 private void readObject(ObjectInputStream ois)
1345 throws ClassNotFoundException, IOException
1347 ois.defaultReadObject();
1349 // If the file was from an OS with a different dir separator,
1350 // fixup the path to use the separator on this OS.
1351 char oldSeparatorChar = ois.readChar();
1353 if (oldSeparatorChar != separatorChar)
1354 path = path.replace(oldSeparatorChar, separatorChar);