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 tests whether or not the current thread is allowed to
168 * to execute the file pointed to by this object. This will be true if and
169 * and only if 1) the file exists and 2) the <code>SecurityManager</code>
170 * (if any) allows access to the file via it's <code>checkExec</code>
171 * method 3) the file is executable.
173 * @return <code>true</code> if execution is allowed,
174 * <code>false</code> otherwise
176 * @exception SecurityException If the <code>SecurityManager</code>
177 * does not allow access to the file
179 public boolean canExecute()
181 if (!VMFile.exists(path))
186 return VMFile.canExecute(path);
190 * This method creates a new file of zero length with the same name as
191 * the path of this <code>File</code> object if an only if that file
192 * does not already exist.
194 * A <code>SecurityManager.checkWrite</code> check is done prior
195 * to performing this action.
197 * @return <code>true</code> if the file was created, <code>false</code> if
198 * the file alread existed.
200 * @exception IOException If an I/O error occurs
201 * @exception SecurityException If the <code>SecurityManager</code> will
202 * not allow this operation to be performed.
206 public boolean createNewFile() throws IOException
209 return VMFile.create(path);
212 * This method deletes the file represented by this object. If this file
213 * is a directory, it must be empty in order for the delete to succeed.
215 * @return <code>true</code> if the file was deleted, <code>false</code>
218 * @exception SecurityException If deleting of the file is not allowed
220 public synchronized boolean delete()
222 SecurityManager s = System.getSecurityManager();
227 return VMFile.delete(path);
231 * This method tests two <code>File</code> objects for equality by
232 * comparing the path of the specified <code>File</code> against the path
233 * of this object. The two objects are equal if an only if 1) The
234 * argument is not null 2) The argument is a <code>File</code> object and
235 * 3) The path of the <code>File</code>argument is equal to the path
238 * The paths of the files are determined by calling the
239 * <code>getPath()</code>
240 * method on each object.
242 * @return <code>true</code> if the two objects are equal,
243 * <code>false</code> otherwise.
245 public boolean equals(Object obj)
247 if (! (obj instanceof File))
250 File other = (File) obj;
252 if (VMFile.IS_CASE_SENSITIVE)
253 return path.equals(other.path);
255 return path.equalsIgnoreCase(other.path);
259 * This method tests whether or not the file represented by the object
260 * actually exists on the filesystem.
262 * @return <code>true</code> if the file exists, <code>false</code>otherwise.
264 * @exception SecurityException If reading of the file is not permitted
266 public boolean exists()
269 return VMFile.exists(path);
273 * This method initializes a new <code>File</code> object to represent
274 * a file with the specified path.
276 * @param name The path name of the file
278 public File(String name)
280 path = normalizePath (name);
283 // Remove duplicate and redundant separator characters.
284 private String normalizePath(String p)
286 // On Windows, convert any '/' to '\'. This appears to be the same logic
287 // that Sun's Win32 Java performs.
288 if (separatorChar == '\\')
290 p = p.replace ('/', '\\');
291 // We have to special case the "\c:" prefix.
292 if (p.length() > 2 && p.charAt(0) == '\\' &&
293 ((p.charAt(1) >= 'a' && p.charAt(1) <= 'z') ||
294 (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z')) &&
299 int dupIndex = p.indexOf(dupSeparator);
300 int plen = p.length();
302 // Special case: permit Windows UNC path prefix.
303 if (dupSeparator.equals("\\\\") && dupIndex == 0)
304 dupIndex = p.indexOf(dupSeparator, 1);
308 // Ignore trailing separator (though on Windows "a:\", for
309 // example, is a valid and minimal path).
310 if (plen > 1 && p.charAt (plen - 1) == separatorChar)
312 if (! (separatorChar == '\\' && ((plen == 3 && p.charAt(1) == ':')
313 || (plen == 2 && p.charAt(0) == separatorChar))))
314 return p.substring (0, plen - 1);
320 StringBuffer newpath = new StringBuffer(plen);
322 while (dupIndex != -1)
324 newpath.append(p.substring(last, dupIndex));
325 // Ignore the duplicate path characters.
326 while (p.charAt(dupIndex) == separatorChar)
329 if (dupIndex == plen)
331 if ((separatorChar == '\\'
332 && newpath.length() == 2
333 && newpath.charAt(1) == ':')
334 || (separatorChar != '\\' && newpath.length() == 0))
336 newpath.append(separatorChar);
338 return newpath.toString();
341 newpath.append(separatorChar);
343 dupIndex = p.indexOf(dupSeparator, last);
346 // Again, ignore possible trailing separator (except special cases
347 // like "a:\" on Windows).
349 if (plen > 1 && p.charAt (plen - 1) == separatorChar)
351 if (separatorChar == '\\'
352 && ((plen == 3 && p.charAt(1) == ':')
353 || (plen == 2 && p.charAt(0) == separatorChar)))
360 newpath.append(p.substring(last, end));
362 return newpath.toString();
366 * This method initializes a new <code>File</code> object to represent
367 * a file in the specified named directory. The path name to the file
368 * will be the directory name plus the separator string plus the file
369 * name. If the directory path name ends in the separator string, another
370 * separator string will still be appended.
372 * @param dirPath The path to the directory the file resides in
373 * @param name The name of the file
375 public File(String dirPath, String name)
378 throw new NullPointerException();
381 if (dirPath.length() > 0)
383 // Try to be smart about the number of separator characters.
384 if (dirPath.charAt(dirPath.length() - 1) == separatorChar
385 || name.length() == 0)
386 path = normalizePath(dirPath + name);
388 path = normalizePath(dirPath + separatorChar + name);
392 // If dirPath is empty, use a system dependant
394 // Note that the leading separators in name have
395 // to be chopped off, to prevent them forming
396 // a UNC prefix on Windows.
397 if (separatorChar == '\\' /* TODO use ON_WINDOWS */)
400 while(name.length() > skip
401 && (name.charAt(skip) == separatorChar
402 || name.charAt(skip) == '/'))
406 name = name.substring(skip);
408 path = normalizePath(separatorChar + name);
412 path = normalizePath(name);
416 * This method initializes a new <code>File</code> object to represent
417 * a file in the specified directory. If the <code>directory</code>
418 * argument is <code>null</code>, the file is assumed to be in the
419 * current directory as specified by the <code>user.dir</code> system
422 * @param directory The directory this file resides in
423 * @param name The name of the file
425 public File(File directory, String name)
427 this (directory == null ? null : directory.path, name);
431 * This method initializes a new <code>File</code> object to represent
432 * a file corresponding to the specified <code>file:</code> protocol URI.
435 * @throws IllegalArgumentException if the URI is not hierarchical
440 throw new NullPointerException("uri is null");
442 if (!uri.getScheme().equals("file"))
443 throw new IllegalArgumentException("invalid uri protocol");
445 String name = uri.getPath();
447 throw new IllegalArgumentException("URI \"" + uri
448 + "\" is not hierarchical");
449 path = normalizePath(name);
453 * This method returns the path of this file as an absolute path name.
454 * If the path name is already absolute, then it is returned. Otherwise
455 * the value returned is the current directory plus the separatory
456 * string plus the path of the file. The current directory is determined
457 * from the <code>user.dir</code> system property.
459 * @return The absolute path of this file
461 public String getAbsolutePath()
466 return VMFile.getAbsolutePath(path);
470 * This method returns a <code>File</code> object representing the
471 * absolute path of this object.
473 * @return A <code>File</code> with the absolute path of the object.
477 public File getAbsoluteFile()
479 return new File(getAbsolutePath());
483 * This method returns a canonical representation of the pathname of
484 * this file. The actual form of the canonical representation is
485 * system-dependent. On the GNU system, conversion to canonical
486 * form involves the removal of redundant separators, references to
487 * "." and "..", and symbolic links.
489 * Note that this method, unlike the other methods which return path
490 * names, can throw an IOException. This is because native method
491 * might be required in order to resolve the canonical path
493 * @exception IOException If an error occurs
495 public String getCanonicalPath() throws IOException
497 // On Windows, getAbsolutePath might end up calling us, so we
498 // have to special case that call to avoid infinite recursion.
499 if (separatorChar == '\\' && path.length() == 2 &&
500 ((path.charAt(0) >= 'a' && path.charAt(0) <= 'z') ||
501 (path.charAt(0) >= 'A' && path.charAt(0) <= 'Z')) &&
502 path.charAt(1) == ':')
504 return VMFile.toCanonicalForm(path);
506 // Call getAbsolutePath first to make sure that we do the
507 // current directory handling, because the native code
508 // may have a different idea of the current directory.
509 return VMFile.toCanonicalForm(getAbsolutePath());
513 * This method returns a <code>File</code> object representing the
514 * canonical path of this object.
516 * @return A <code>File</code> instance representing the canonical path of
519 * @exception IOException If an error occurs.
523 public File getCanonicalFile() throws IOException
525 return new File(getCanonicalPath());
529 * This method returns the name of the file. This is everything in the
530 * complete path of the file after the last instance of the separator
533 * @return The file name
535 public String getName()
537 return VMFile.getName(path);
541 * This method returns a <code>String</code> the represents this file's
542 * parent. <code>null</code> is returned if the file has no parent. The
543 * parent is determined via a simple operation which removes the name
544 * after the last file separator character, as determined by the platform.
546 * @return The parent directory of this file
548 public String getParent()
550 String prefix = null;
551 int nameSeqIndex = 0;
556 // The "prefix", if present, is the leading "/" on UNIX and
557 // either the drive specifier (e.g. "C:") or the leading "\\"
558 // of a UNC network path on Windows.
559 if (separatorChar == '/' && path.charAt (0) == '/')
564 else if (separatorChar == '\\' && path.length() > 1)
566 if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
567 || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
568 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
569 && path.charAt (1) == ':'))
571 prefix = path.substring (0, 2);
576 // According to the JDK docs, the returned parent path is the
577 // portion of the name sequence before the last separator
578 // character, if found, prefixed by the prefix, otherwise null.
579 if (nameSeqIndex < path.length())
581 String nameSeq = path.substring (nameSeqIndex, path.length());
582 int last = nameSeq.lastIndexOf (separatorChar);
585 else if (last == (nameSeq.length() - 1))
586 // Note: The path would not have a trailing separator
587 // except for cases like "C:\" on Windows (see
588 // normalizePath( )), where Sun's JRE 1.4 returns null.
594 return prefix + nameSeq.substring (0, last);
596 return nameSeq.substring (0, last);
599 // Sun's JRE 1.4 returns null if the prefix is the only
600 // component of the path - so "/" gives null on UNIX and
601 // "C:", "\\", etc. return null on Windows.
606 * This method returns a <code>File</code> object representing the parent
609 * @return a <code>File</code> for the parent of this object.
611 * will be returned if this object does not have a parent.
615 public File getParentFile()
617 String parent = getParent();
618 return parent != null ? new File(parent) : null;
622 * Returns the path name that represents this file. May be a relative
623 * or an absolute path name
625 * @return The pathname of this file
627 public String getPath()
633 * This method returns a hash code representing this file. It is the
634 * hash code of the path of this file (as returned by <code>getPath()</code>)
635 * exclusived or-ed with the value 1234321.
637 * @return The hash code for this object
639 public int hashCode()
641 if (VMFile.IS_CASE_SENSITIVE)
642 return path.hashCode() ^ 1234321;
644 return path.toLowerCase().hashCode() ^ 1234321;
648 * This method returns true if this object represents an absolute file
649 * path and false if it does not. The definition of an absolute path varies
650 * by system. As an example, on GNU systems, a path is absolute if it starts
653 * @return <code>true</code> if this object represents an absolute
654 * file name, <code>false</code> otherwise.
656 public boolean isAbsolute()
658 return VMFile.isAbsolute(path);
662 * This method tests whether or not the file represented by this object
663 * is a directory. In order for this method to return <code>true</code>,
664 * the file represented by this object must exist and be a directory.
666 * @return <code>true</code> if this file is a directory, <code>false</code>
669 * @exception SecurityException If reading of the file is not permitted
671 public boolean isDirectory()
674 return VMFile.isDirectory(path);
678 * This method tests whether or not the file represented by this object
679 * is a "plain" file. A file is a plain file if and only if it 1) Exists,
680 * 2) Is not a directory or other type of special file.
682 * @return <code>true</code> if this is a plain file, <code>false</code>
685 * @exception SecurityException If reading of the file is not permitted
687 public boolean isFile()
690 return VMFile.isFile(path);
694 * This method tests whether or not this file represents a "hidden" file.
695 * On GNU systems, a file is hidden if its name begins with a "."
696 * character. Files with these names are traditionally not shown with
697 * directory listing tools.
699 * @return <code>true</code> if the file is hidden, <code>false</code>
704 public boolean isHidden()
706 return VMFile.isHidden(path);
710 * This method returns the last modification time of this file. The
711 * time value returned is an abstract value that should not be interpreted
712 * as a specified time value. It is only useful for comparing to other
713 * such time values returned on the same system. In that case, the larger
714 * value indicates a more recent modification time.
716 * If the file does not exist, then a value of 0 is returned.
718 * @return The last modification time of the file
720 * @exception SecurityException If reading of the file is not permitted
722 public long lastModified()
725 return VMFile.lastModified(path);
729 * This method returns the length of the file represented by this object,
730 * or 0 if the specified file does not exist.
732 * @return The length of the file
734 * @exception SecurityException If reading of the file is not permitted
739 return VMFile.length(path);
743 * This method returns a array of <code>String</code>'s representing the
744 * list of files is then directory represented by this object. If this
745 * object represents a non-directory file or a non-existent file, then
746 * <code>null</code> is returned. The list of files will not contain
747 * any names such as "." or ".." which indicate the current or parent
748 * directory. Also, the names are not guaranteed to be sorted.
750 * In this form of the <code>list()</code> method, a filter is specified
751 * that allows the caller to control which files are returned in the
752 * list. The <code>FilenameFilter</code> specified is called for each
753 * file returned to determine whether or not that file should be included
756 * A <code>SecurityManager</code> check is made prior to reading the
757 * directory. If read access to the directory is denied, an exception
760 * @param filter An object which will identify files to exclude from
761 * the directory listing.
763 * @return An array of files in the directory, or <code>null</code>
764 * if this object does not represent a valid directory.
766 * @exception SecurityException If read access is not allowed to the
767 * directory by the <code>SecurityManager</code>
769 public String[] list(FilenameFilter filter)
773 if (!exists() || !isDirectory())
776 // Get the list of files
777 String files[] = VMFile.list(path);
779 // Check if an error occured in listInternal().
780 // This is an unreadable directory, pretend there is nothing inside.
782 return new String[0];
789 for (int i = 0; i < files.length; i++)
791 if (filter.accept(this, files[i]))
797 String[] retfiles = new String[count];
799 for (int i = 0; i < files.length; i++)
800 if (files[i] != null)
801 retfiles[count++] = files[i];
807 * This method returns a array of <code>String</code>'s representing the
808 * list of files is then directory represented by this object. If this
809 * object represents a non-directory file or a non-existent file, then
810 * <code>null</code> is returned. The list of files will not contain
811 * any names such as "." or ".." which indicate the current or parent
812 * directory. Also, the names are not guaranteed to be sorted.
814 * A <code>SecurityManager</code> check is made prior to reading the
815 * directory. If read access to the directory is denied, an exception
818 * @return An array of files in the directory, or <code>null</code> if
819 * this object does not represent a valid directory.
821 * @exception SecurityException If read access is not allowed to the
822 * directory by the <code>SecurityManager</code>
824 public String[] list()
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 * A <code>SecurityManager</code> check is made prior to reading the
837 * directory. If read access to the directory is denied, an exception
840 * @return An array of <code>File</code> objects for this directory.
842 * @exception SecurityException If the <code>SecurityManager</code> denies
843 * access to this directory.
847 public File[] listFiles()
849 return listFiles((FilenameFilter) null);
853 * This method returns an array of <code>File</code> objects representing
854 * all the files in the directory represented by this object. If this
855 * object does not represent a directory, <code>null</code> is returned.
856 * Each of the returned <code>File</code> object is constructed with this
857 * object as its parent.
859 * In this form of the <code>listFiles()</code> method, a filter is specified
860 * that allows the caller to control which files are returned in the
861 * list. The <code>FilenameFilter</code> specified is called for each
862 * file returned to determine whether or not that file should be included
865 * A <code>SecurityManager</code> check is made prior to reading the
866 * directory. If read access to the directory is denied, an exception
869 * @return An array of <code>File</code> objects for this directory.
871 * @exception SecurityException If the <code>SecurityManager</code> denies
872 * access to this directory.
876 public File[] listFiles(FilenameFilter filter)
878 String[] filelist = list(filter);
880 if (filelist == null)
883 File[] fobjlist = new File [filelist.length];
885 for (int i = 0; i < filelist.length; i++)
886 fobjlist [i] = new File(this, filelist [i]);
892 * This method returns an array of <code>File</code> objects representing
893 * all the files in the directory represented by this object. If this
894 * object does not represent a directory, <code>null</code> is returned.
895 * Each of the returned <code>File</code> object is constructed with this
896 * object as its parent.
898 * In this form of the <code>listFiles()</code> method, a filter is specified
899 * that allows the caller to control which files are returned in the
900 * list. The <code>FileFilter</code> specified is called for each
901 * file returned to determine whether or not that file should be included
904 * A <code>SecurityManager</code> check is made prior to reading the
905 * directory. If read access to the directory is denied, an exception
908 * @return An array of <code>File</code> objects for this directory.
910 * @exception SecurityException If the <code>SecurityManager</code> denies
911 * access to this directory.
915 public File[] listFiles(FileFilter filter)
917 File[] fobjlist = listFiles((FilenameFilter) null);
919 if (fobjlist == null)
926 for (int i = 0; i < fobjlist.length; i++)
927 if (filter.accept(fobjlist[i]) == true)
930 File[] final_list = new File[count];
932 for (int i = 0; i < fobjlist.length; i++)
933 if (filter.accept(fobjlist[i]) == true)
935 final_list[count] = fobjlist[i];
943 * This method returns a <code>String</code> that is the path name of the
944 * file as returned by <code>getPath</code>.
946 * @return A <code>String</code> representation of this file
948 public String toString()
954 * @return A <code>URI</code> for this object.
958 String abspath = getAbsolutePath();
960 if (isDirectory() || path.equals(""))
961 abspath = abspath + separatorChar;
963 if (separatorChar == '\\')
964 abspath = separatorChar + abspath;
968 return new URI("file", null, null, -1,
969 abspath.replace(separatorChar, '/'),
972 catch (URISyntaxException use)
975 throw (InternalError) new InternalError("Unconvertible file: "
976 + this).initCause(use);
981 * This method returns a <code>URL</code> with the <code>file:</code>
982 * protocol that represents this file. The exact form of this URL is
985 * @return A <code>URL</code> for this object.
987 * @exception MalformedURLException If the URL cannot be created
990 public URL toURL() throws MalformedURLException
992 return VMFile.toURL(this);
997 * This method creates a directory for the path represented by this object.
999 * @return <code>true</code> if the directory was created,
1000 * <code>false</code> otherwise
1002 * @exception SecurityException If write access is not allowed to this file
1004 public boolean mkdir()
1007 return VMFile.mkdir(path);
1011 * This method creates a directory for the path represented by this file.
1012 * It will also create any intervening parent directories if necessary.
1014 * @return <code>true</code> if the directory was created,
1015 * <code>false</code> otherwise
1017 * @exception SecurityException If write access is not allowed to this file
1019 public boolean mkdirs()
1021 String parent = getParent();
1027 File f = new File(parent);
1030 boolean rc = f.mkdirs();
1039 * This method creates a temporary file in the specified directory. If
1040 * the directory name is null, then this method uses the system temporary
1041 * directory. The files created are guaranteed not to currently exist and
1042 * the same file name will never be used twice in the same virtual
1044 * The system temporary directory is determined by examinging the
1045 * <code>java.io.tmpdir</code> system property.
1047 * The <code>prefix</code> parameter is a sequence of at least three
1048 * characters that are used as the start of the generated filename. The
1049 * <code>suffix</code> parameter is a sequence of characters that is used
1050 * to terminate the file name. This parameter may be <code>null</code>
1051 * and if it is, the suffix defaults to ".tmp".
1053 * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1054 * method is used to verify that this operation is permitted.
1056 * @param prefix The character prefix to use in generating the path name.
1057 * @param suffix The character suffix to use in generating the path name.
1058 * @param directory The directory to create the file in, or
1059 * <code>null</code> for the default temporary directory
1061 * @exception IllegalArgumentException If the patterns is not valid
1062 * @exception SecurityException If there is no permission to perform
1064 * @exception IOException If an error occurs
1068 public static synchronized File createTempFile(String prefix, String suffix,
1072 // Grab the system temp directory if necessary
1073 if (directory == null)
1075 String dirname = System.getProperty("java.io.tmpdir");
1076 if (dirname == null)
1077 throw new IOException("Cannot determine system temporary directory");
1079 directory = new File(dirname);
1080 if (! VMFile.exists(directory.path))
1081 throw new IOException("System temporary directory "
1082 + directory.getName() + " does not exist.");
1083 if (! VMFile.isDirectory(directory.path))
1084 throw new IOException("System temporary directory "
1085 + directory.getName()
1086 + " is not really a directory.");
1089 // Check if prefix is at least 3 characters long
1090 if (prefix.length() < 3)
1091 throw new IllegalArgumentException("Prefix too short: " + prefix);
1093 // Set default value of suffix
1097 // Now identify a file name and make sure it doesn't exist.
1099 if (!VMFile.IS_DOS_8_3)
1103 long now = System.currentTimeMillis();
1106 // The last temporary file was created more than 1 ms ago.
1113 String name = Long.toHexString(now);
1115 name += '_'+Integer.toHexString(n_created);
1116 String filename = prefix + name + suffix;
1117 file = new File(directory, filename);
1119 while (VMFile.exists(file.path));
1123 // make sure prefix is not longer than 7 characters
1124 if (prefix.length() >= 8)
1125 throw new IllegalArgumentException("Prefix too long: " + prefix + "(valid length 3..7)");
1127 long mask = 0x000000ffffFFFFL >> (prefix.length() * 4);
1130 int n = (int) (System.currentTimeMillis() & mask);
1131 String filename = prefix + java.lang.Integer.toHexString(n) + suffix;
1132 file = new File(directory, filename);
1134 while (VMFile.exists(file.path));
1137 // Verify that we are allowed to create this file
1138 SecurityManager sm = System.getSecurityManager();
1140 sm.checkWrite(file.getAbsolutePath());
1142 // Now create the file and return our file object
1143 // XXX - FIXME race condition.
1144 VMFile.create(file.getAbsolutePath());
1149 * This method sets the owner's read permission for the File represented by
1152 * It is the same as calling <code>setReadable(readable, true)</code>.
1154 * @param <code>readable</code> <code>true</code> to set read permission,
1155 * <code>false</code> to unset the read permission.
1156 * @return <code>true</code> if the file permissions are changed,
1157 * <code>false</code> otherwise.
1158 * @exception SecurityException If write access of the file is not permitted.
1159 * @see #setReadable(boolean, boolean)
1162 public boolean setReadable(boolean readable)
1164 return setReadable(readable, true);
1168 * This method sets the read permissions for the File represented by
1171 * If <code>ownerOnly</code> is set to <code>true</code> then only the
1172 * read permission bit for the owner of the file is changed.
1174 * If <code>ownerOnly</code> is set to <code>false</code>, the file
1175 * permissions are changed so that the file can be read by everyone.
1177 * On unix like systems this sets the <code>user</code>, <code>group</code>
1178 * and <code>other</code> read bits and is equal to call
1179 * <code>chmod a+r</code> on the file.
1181 * @param <code>readable</code> <code>true</code> to set read permission,
1182 * <code>false</code> to unset the read permission.
1183 * @param <code>ownerOnly</code> <code>true</code> to set read permission
1184 * for owner only, <code>false</code> for all.
1185 * @return <code>true</code> if the file permissions are changed,
1186 * <code>false</code> otherwise.
1187 * @exception SecurityException If write access of the file is not permitted.
1188 * @see #setReadable(boolean)
1191 public boolean setReadable(boolean readable, boolean ownerOnly)
1194 return VMFile.setReadable(path, readable, ownerOnly);
1198 * This method sets the owner's write permission for the File represented by
1201 * It is the same as calling <code>setWritable(readable, true)</code>.
1203 * @param <code>writable</code> <code>true</code> to set write permission,
1204 * <code>false</code> to unset write permission.
1205 * @return <code>true</code> if the file permissions are changed,
1206 * <code>false</code> otherwise.
1207 * @exception SecurityException If write access of the file is not permitted.
1208 * @see #setWritable(boolean, boolean)
1211 public boolean setWritable(boolean writable)
1213 return setWritable(writable, true);
1217 * This method sets the write permissions for the File represented by
1220 * If <code>ownerOnly</code> is set to <code>true</code> then only the
1221 * write permission bit for the owner of the file is changed.
1223 * If <code>ownerOnly</code> is set to <code>false</code>, the file
1224 * permissions are changed so that the file can be written by everyone.
1226 * On unix like systems this set the <code>user</code>, <code>group</code>
1227 * and <code>other</code> write bits and is equal to call
1228 * <code>chmod a+w</code> on the file.
1230 * @param <code>writable</code> <code>true</code> to set write permission,
1231 * <code>false</code> to unset write permission.
1232 * @param <code>ownerOnly</code> <code>true</code> to set write permission
1233 * for owner only, <code>false</code> for all.
1234 * @return <code>true</code> if the file permissions are changed,
1235 * <code>false</code> otherwise.
1236 * @exception SecurityException If write access of the file is not permitted.
1237 * @see #setWritable(boolean)
1240 public boolean setWritable(boolean writable, boolean ownerOnly)
1243 return VMFile.setWritable(path, writable, ownerOnly);
1247 * This method sets the owner's execute permission for the File represented
1250 * It is the same as calling <code>setExecutable(readable, true)</code>.
1252 * @param <code>executable</code> <code>true</code> to set execute permission,
1253 * <code>false</code> to unset execute permission.
1254 * @return <code>true</code> if the file permissions are changed,
1255 * <code>false</code> otherwise.
1256 * @exception SecurityException If write access of the file is not permitted.
1257 * @see #setExecutable(boolean, boolean)
1260 public boolean setExecutable(boolean executable)
1262 return setExecutable(executable, true);
1266 * This method sets the execute permissions for the File represented by
1269 * If <code>ownerOnly</code> is set to <code>true</code> then only the
1270 * execute permission bit for the owner of the file is changed.
1272 * If <code>ownerOnly</code> is set to <code>false</code>, the file
1273 * permissions are changed so that the file can be executed by everyone.
1275 * On unix like systems this set the <code>user</code>, <code>group</code>
1276 * and <code>other</code> write bits and is equal to call
1277 * <code>chmod a+x</code> on the file.
1279 * @param <code>executable</code> <code>true</code> to set write permission,
1280 * <code>false</code> to unset write permission.
1281 * @param <code>ownerOnly</code> <code>true</code> to set write permission
1282 * for owner only, <code>false</code> for all.
1283 * @return <code>true</code> if the file permissions are changed,
1284 * <code>false</code> otherwise.
1285 * @exception SecurityException If write access of the file is not permitted.
1286 * @see #setExecutable(boolean)
1289 public boolean setExecutable(boolean executable, boolean ownerOnly)
1292 return VMFile.setExecutable(path, executable, ownerOnly);
1296 * This method sets the file represented by this object to be read only.
1297 * A read only file or directory cannot be modified. Please note that
1298 * GNU systems allow read only files to be deleted if the directory it
1299 * is contained in is writable.
1301 * @return <code>true</code> if the operation succeeded, <code>false</code>
1304 * @exception SecurityException If the <code>SecurityManager</code> does
1305 * not allow this operation.
1309 public boolean setReadOnly()
1311 // Do a security check before trying to do anything else.
1314 // Test for existence.
1315 if (! VMFile.exists(path))
1318 return VMFile.setReadOnly(path);
1322 * This method returns an array of filesystem roots. Some operating systems
1323 * have volume oriented filesystem. This method provides a mechanism for
1324 * determining which volumes exist. GNU systems use a single hierarchical
1325 * filesystem, so will have only one "/" filesystem root.
1327 * @return An array of <code>File</code> objects for each filesystem root
1332 public static File[] listRoots()
1334 File[] roots = VMFile.listRoots();
1336 SecurityManager s = System.getSecurityManager();
1339 // Only return roots to which the security manager permits read access.
1340 int count = roots.length;
1341 for (int i = 0; i < roots.length; i++)
1345 s.checkRead (roots[i].path);
1347 catch (SecurityException sx)
1353 if (count != roots.length)
1355 File[] newRoots = new File[count];
1357 for (int i = 0; i < roots.length; i++)
1359 if (roots[i] != null)
1360 newRoots[k++] = roots[i];
1369 * This method creates a temporary file in the system temporary directory.
1370 * The files created are guaranteed not to currently exist and the same file
1371 * name will never be used twice in the same virtual machine instance. The
1372 * system temporary directory is determined by examinging the
1373 * <code>java.io.tmpdir</code> system property.
1375 * The <code>prefix</code> parameter is a sequence of at least three
1376 * characters that are used as the start of the generated filename. The
1377 * <code>suffix</code> parameter is a sequence of characters that is used
1378 * to terminate the file name. This parameter may be <code>null</code>
1379 * and if it is, the suffix defaults to ".tmp".
1381 * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1382 * method is used to verify that this operation is permitted.
1384 * This method is identical to calling
1385 * <code>createTempFile(prefix, suffix, null)</code>.
1387 * @param prefix The character prefix to use in generating the path name.
1388 * @param suffix The character suffix to use in generating the path name.
1390 * @exception IllegalArgumentException If the prefix or suffix are not valid.
1391 * @exception SecurityException If there is no permission to perform
1393 * @exception IOException If an error occurs
1395 public static File createTempFile(String prefix, String suffix)
1398 return createTempFile(prefix, suffix, null);
1402 * This method compares the specified <code>File</code> to this one
1403 * to test for equality. It does this by comparing the canonical path names
1406 * The canonical paths of the files are determined by calling the
1407 * <code>getCanonicalPath</code> method on each object.
1409 * This method returns a 0 if the specified <code>Object</code> is equal
1410 * to this one, a negative value if it is less than this one
1411 * a positive value if it is greater than this one.
1413 * @return An integer as described above
1417 public int compareTo(File other)
1419 if (VMFile.IS_CASE_SENSITIVE)
1420 return path.compareTo (other.path);
1422 return path.compareToIgnoreCase (other.path);
1426 * This method renames the file represented by this object to the path
1427 * of the file represented by the argument <code>File</code>.
1429 * @param dest The <code>File</code> object representing the target name
1431 * @return <code>true</code> if the rename succeeds, <code>false</code>
1434 * @exception SecurityException If write access is not allowed to the
1435 * file by the <code>SecurityMananger</code>.
1437 public synchronized boolean renameTo(File dest)
1441 // Call our native rename method
1442 return VMFile.renameTo(path, dest.path);
1446 * This method sets the modification time on the file to the specified
1447 * value. This is specified as the number of seconds since midnight
1448 * on January 1, 1970 GMT.
1450 * @param time The desired modification time.
1452 * @return <code>true</code> if the operation succeeded, <code>false</code>
1455 * @exception IllegalArgumentException If the specified time is negative.
1456 * @exception SecurityException If the <code>SecurityManager</code> will
1457 * not allow this operation.
1461 public boolean setLastModified(long time)
1464 throw new IllegalArgumentException("Negative modification time: " + time);
1467 return VMFile.setLastModified(path, time);
1470 private void checkWrite()
1472 // Check the SecurityManager
1473 SecurityManager s = System.getSecurityManager();
1479 private void checkRead()
1481 // Check the SecurityManager
1482 SecurityManager s = System.getSecurityManager();
1488 private void checkExec()
1490 // Check the SecurityManager
1491 SecurityManager s = System.getSecurityManager();
1498 * Calling this method requests that the file represented by this object
1499 * be deleted when the virtual machine exits. Note that this request cannot
1500 * be cancelled. Also, it will only be carried out if the virtual machine
1503 * @exception SecurityException If deleting of the file is not allowed
1507 public void deleteOnExit()
1509 // Check the SecurityManager
1510 SecurityManager sm = System.getSecurityManager();
1512 sm.checkDelete(path);
1514 DeleteFileHelper.add(this);
1517 private void writeObject(ObjectOutputStream oos) throws IOException
1519 oos.defaultWriteObject();
1520 oos.writeChar(separatorChar);
1523 private void readObject(ObjectInputStream ois)
1524 throws ClassNotFoundException, IOException
1526 ois.defaultReadObject();
1528 // If the file was from an OS with a different dir separator,
1529 // fixup the path to use the separator on this OS.
1530 char oldSeparatorChar = ois.readChar();
1532 if (oldSeparatorChar != separatorChar)
1533 path = path.replace(oldSeparatorChar, separatorChar);