1 // File.java - File name
3 /* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
15 import gnu.gcj.runtime.FileDeleter;
18 * @author Tom Tromey <tromey@cygnus.com>
19 * @date September 24, 1998
22 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
23 * "The Java Language Specification", ISBN 0-201-63451-1
24 * Status: Complete to version 1.3.
27 public class File implements Serializable, Comparable
29 public boolean canRead ()
35 public boolean canWrite ()
38 return access (WRITE);
41 private native boolean performCreate() throws IOException;
44 public boolean createNewFile() throws IOException
47 return performCreate();
50 private native boolean performDelete ();
51 public boolean delete ()
53 SecurityManager s = System.getSecurityManager();
57 return performDelete ();
60 public boolean equals (Object obj)
62 if (! (obj instanceof File))
64 File other = (File) obj;
66 return (path.equals(other.path));
68 return (path.equalsIgnoreCase(other.path));
71 public boolean exists ()
74 return access (EXISTS);
77 public File (String p)
80 throw new NullPointerException ();
84 public File (String dirPath, String name)
87 throw new NullPointerException ();
88 if (dirPath != null && dirPath.length() > 0)
90 // Try to be smart about the number of separator characters.
91 if (dirPath.charAt(dirPath.length() - 1) == separatorChar)
92 path = dirPath + name;
94 path = dirPath + separatorChar + name;
100 public File (File dir, String name)
102 this (dir == null ? null : dir.path, name);
106 public String getAbsolutePath ()
110 return System.getProperty("user.dir") + separatorChar + path;
114 public File getAbsoluteFile () throws IOException
116 return new File (getAbsolutePath());
119 public native String getCanonicalPath () throws IOException;
122 public File getCanonicalFile () throws IOException
124 return new File (getCanonicalPath());
127 public String getName ()
129 int last = path.lastIndexOf(separatorChar);
130 return path.substring(last + 1);
133 public String getParent ()
135 int last = path.lastIndexOf(separatorChar);
138 return path.substring(0, last);
142 public File getParentFile ()
144 String parent = getParent ();
145 return (parent == null ? null : new File (parent));
148 public String getPath ()
153 public int hashCode ()
156 return (path.hashCode() ^ 1234321);
158 return (path.toLowerCase().hashCode() ^ 1234321);
161 public native boolean isAbsolute ();
163 public boolean isDirectory ()
166 return stat (DIRECTORY);
169 public boolean isFile ()
172 return stat (ISFILE);
176 public boolean isHidden()
179 return stat (ISHIDDEN);
182 public long lastModified ()
185 return attr (MODIFIED);
188 public long length ()
191 return attr (LENGTH);
194 private final native Object[] performList (FilenameFilter filter,
195 FileFilter fileFilter,
198 // Arguments for the performList function. Specifies whether we want
199 // File objects or path strings in the returned object array.
200 private final static int OBJECTS = 0;
201 private final static int STRINGS = 1;
203 public String[] list (FilenameFilter filter)
206 return (String[]) performList (filter, null, String.class);
209 public String[] list ()
212 return (String[]) performList (null, null, String.class);
216 public File[] listFiles()
219 return (File[]) performList (null, null, File.class);
223 public File[] listFiles(FilenameFilter filter)
226 return (File[]) performList (filter, null, File.class);
230 public File[] listFiles(FileFilter filter)
233 return (File[]) performList (null, filter, File.class);
236 public String toString ()
241 public URL toURL () throws MalformedURLException
243 return new URL ("file:" + path + (isDirectory() ? "/" : ""));
246 private final native boolean performMkdir ();
248 public boolean mkdir ()
251 return performMkdir ();
254 private static boolean mkdirs (File x)
258 String p = x.getPath();
259 String parent = x.getParent();
270 public boolean mkdirs ()
275 return mkdirs (new File (path));
278 private static synchronized String nextValue ()
280 return Long.toString(counter++, Character.MAX_RADIX);
284 public static File createTempFile (String prefix, String suffix,
288 // Grab the system temp directory if necessary
289 if (directory == null)
291 String dirname = tmpdir;
294 new IOException("Cannot determine system temporary directory");
296 directory = new File(dirname);
297 if (!directory.exists())
298 throw new IOException("System temporary directory "
299 + directory.getName() + " does not exist.");
300 if (!directory.isDirectory())
301 throw new IOException("System temporary directory "
302 + directory.getName()
303 + " is not really a directory.");
306 if (prefix.length () < 3)
307 throw new IllegalArgumentException ("Prefix too short: " + prefix);
312 // `6' is the number of characters we generate.
313 if (prefix.length () + 6 + suffix.length () > maxPathLen)
316 if (suffix.charAt(0) == '.')
318 suffix = suffix.substring(0, suf_len);
319 if (prefix.length () + 6 + suf_len > maxPathLen)
320 prefix = prefix.substring(0, maxPathLen - 6 - suf_len);
325 // How many times should we try? We choose 100.
326 for (int i = 0; i < 100; ++i)
329 String t = "ZZZZZZ" + nextValue ();
330 String l = prefix + t.substring(t.length() - 6) + suffix;
333 f = new File(directory, l);
334 if (f.createNewFile())
337 catch (IOException ignored)
342 throw new IOException ("cannot create temporary file");
345 private native boolean performSetReadOnly();
348 public boolean setReadOnly()
351 return performSetReadOnly();
354 private static native File[] performListRoots();
357 public static File[] listRoots()
359 File[] roots = performListRoots();
361 SecurityManager s = System.getSecurityManager();
364 // Only return roots to which the security manager permits read access.
365 int count = roots.length;
366 for (int i = 0; i < roots.length; i++)
370 s.checkRead(roots[i].path);
372 catch (SecurityException sx)
378 if (count != roots.length)
380 File[] newRoots = new File[count];
382 for (int i=0; i < roots.length; i++)
384 if (roots[i] != null)
385 newRoots[k++] = roots[i];
393 public static File createTempFile (String prefix, String suffix)
396 return createTempFile (prefix, suffix, null);
400 public int compareTo(File other)
403 return path.compareTo (other.path);
405 return path.compareToIgnoreCase (other.path);
409 public int compareTo(Object o)
411 File other = (File) o;
412 return compareTo (other);
415 private native boolean performRenameTo (File dest);
416 public boolean renameTo (File dest)
418 SecurityManager s = System.getSecurityManager();
419 String sname = getName();
420 String dname = dest.getName();
426 return performRenameTo (dest);
429 private native boolean performSetLastModified(long time);
432 public boolean setLastModified(long time)
435 return performSetLastModified(time);
438 public static final String separator = null;
439 public static final String pathSeparator = null;
440 static final String tmpdir = null;
441 static int maxPathLen;
442 static boolean caseSensitive;
444 public static final char separatorChar;
445 public static final char pathSeparatorChar;
450 pathSeparatorChar = pathSeparator.charAt(0);
451 separatorChar = separator.charAt(0);
454 // Native function called at class initialization. This should should
455 // set the separator, pathSeparator, tmpdir, maxPathLen, and caseSensitive
457 private static native void init_native();
462 // We keep a counter for use by createTempFile. We choose the first
463 // value randomly to try to avoid clashes with other VMs.
464 private static long counter = Double.doubleToLongBits (Math.random ());
466 private void checkWrite ()
468 SecurityManager s = System.getSecurityManager();
473 private void checkRead ()
475 SecurityManager s = System.getSecurityManager();
481 * Add this File to the set of files to be deleted upon normal
486 // FIXME: This should use the ShutdownHook API once we implement that.
487 public void deleteOnExit ()
489 SecurityManager sm = System.getSecurityManager ();
491 sm.checkDelete (getName ());
493 FileDeleter.add (this);
496 private void writeObject (ObjectOutputStream oos) throws IOException
498 oos.defaultWriteObject ();
499 oos.writeChar (separatorChar);
502 private void readObject (ObjectInputStream ois)
503 throws ClassNotFoundException, IOException
505 ois.defaultReadObject ();
507 // If the file was from an OS with a different dir separator,
508 // fixup the path to use the separator on this OS.
509 char oldSeparatorChar = ois.readChar ();
510 if (oldSeparatorChar != separatorChar)
511 path = path.replace (oldSeparatorChar, separatorChar);
514 // QUERY arguments to access function.
515 private final static int READ = 0;
516 private final static int WRITE = 1;
517 private final static int EXISTS = 2;
519 // QUERY arguments to stat function.
520 private final static int DIRECTORY = 0;
521 private final static int ISFILE = 1;
522 private final static int ISHIDDEN = 2;
524 // QUERY arguments to attr function.
525 private final static int MODIFIED = 0;
526 private final static int LENGTH = 1;
528 private final native long attr (int query);
529 private final native boolean access (int query);
530 private final native boolean stat (int query);
532 private static final long serialVersionUID = 301077366599181567L;