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 ()
32 return _access (READ
);
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
)
79 path
= normalizePath(p
);
82 // Remove duplicate and redundant separator characters.
83 private String
normalizePath(String p
)
85 // On Windows, convert any '/' to '\'. This appears to be the same logic
86 // that Sun's Win32 Java performs.
87 if (separatorChar
== '\\')
88 p
= p
.replace ('/', '\\');
90 int dupIndex
= p
.indexOf(dupSeparator
);
91 int plen
= p
.length();
93 // Special case: permit Windows UNC path prefix.
94 if (dupSeparator
.equals("\\\\") && dupIndex
== 0)
95 dupIndex
= p
.indexOf(dupSeparator
, 1);
99 // Ignore trailing separator.
100 if (plen
> 1 && p
.charAt(plen
- 1) == separatorChar
)
101 return p
.substring(0, plen
- 1);
106 StringBuffer newpath
= new StringBuffer(plen
);
108 while (dupIndex
!= -1)
110 newpath
.append(p
.substring(last
, dupIndex
));
111 // Ignore the duplicate path characters.
112 while (p
.charAt(dupIndex
) == separatorChar
)
115 if (dupIndex
== plen
)
116 return newpath
.toString();
118 newpath
.append(separatorChar
);
120 dupIndex
= p
.indexOf(dupSeparator
, last
);
123 // Again, ignore possible trailing separator.
125 if (plen
> 1 && p
.charAt(plen
- 1) == separatorChar
)
129 newpath
.append(p
.substring(last
, end
));
131 return newpath
.toString();
134 public File (String dirPath
, String name
)
137 throw new NullPointerException ();
138 if (dirPath
!= null && dirPath
.length() > 0)
140 // Try to be smart about the number of separator characters.
141 if (dirPath
.charAt(dirPath
.length() - 1) == separatorChar
142 || name
.length() == 0)
143 path
= normalizePath(dirPath
+ name
);
145 path
= normalizePath(dirPath
+ separatorChar
+ name
);
148 path
= normalizePath(name
);
151 public File (File dir
, String name
)
153 this (dir
== null ?
null : dir
.path
, name
);
157 public String
getAbsolutePath ()
161 return System
.getProperty("user.dir") + separatorChar
+ path
;
165 public File
getAbsoluteFile ()
167 return new File (getAbsolutePath());
170 public native String
getCanonicalPath () throws IOException
;
173 public File
getCanonicalFile () throws IOException
175 return new File (getCanonicalPath());
178 public String
getName ()
180 int last
= path
.lastIndexOf(separatorChar
);
181 return path
.substring(last
+ 1);
184 public String
getParent ()
186 int last
= path
.lastIndexOf(separatorChar
);
189 // FIXME: POSIX assumption.
190 if (last
== 0 && path
.charAt (0) == '/')
192 return path
.substring(0, last
);
196 public File
getParentFile ()
198 String parent
= getParent ();
199 return (parent
== null ?
null : new File (parent
));
202 public String
getPath ()
207 public int hashCode ()
210 return (path
.hashCode() ^
1234321);
212 return (path
.toLowerCase().hashCode() ^
1234321);
215 public native boolean isAbsolute ();
217 public boolean isDirectory ()
220 return _stat (DIRECTORY
);
223 public boolean isFile ()
226 return _stat (ISFILE
);
230 public boolean isHidden()
233 return _stat (ISHIDDEN
);
236 public long lastModified ()
239 return attr (MODIFIED
);
242 public long length ()
245 return attr (LENGTH
);
248 private final native Object
[] performList (FilenameFilter filter
,
249 FileFilter fileFilter
,
252 public String
[] list (FilenameFilter filter
)
255 return (String
[]) performList (filter
, null, String
.class);
258 public String
[] list ()
261 return (String
[]) performList (null, null, String
.class);
265 public File
[] listFiles()
268 return (File
[]) performList (null, null, File
.class);
272 public File
[] listFiles(FilenameFilter filter
)
275 return (File
[]) performList (filter
, null, File
.class);
279 public File
[] listFiles(FileFilter filter
)
282 return (File
[]) performList (null, filter
, File
.class);
285 public String
toString ()
290 public URL
toURL () throws MalformedURLException
292 return new URL ("file://" + getAbsolutePath ()
293 + (isDirectory() ?
"/" : ""));
296 private final native boolean performMkdir ();
298 public boolean mkdir ()
301 return performMkdir ();
304 private static boolean mkdirs (File x
)
308 String p
= x
.getPath();
309 String parent
= x
.getParent();
320 public boolean mkdirs ()
325 return mkdirs (new File (path
));
328 private static synchronized String
nextValue ()
330 return Long
.toString(counter
++, Character
.MAX_RADIX
);
334 public static File
createTempFile (String prefix
, String suffix
,
338 // Grab the system temp directory if necessary
339 if (directory
== null)
341 String dirname
= tmpdir
;
344 new IOException("Cannot determine system temporary directory");
346 directory
= new File(dirname
);
347 if (!directory
.exists())
348 throw new IOException("System temporary directory "
349 + directory
.getName() + " does not exist.");
350 if (!directory
.isDirectory())
351 throw new IOException("System temporary directory "
352 + directory
.getName()
353 + " is not really a directory.");
356 if (prefix
.length () < 3)
357 throw new IllegalArgumentException ("Prefix too short: " + prefix
);
362 // `6' is the number of characters we generate.
363 if (prefix
.length () + 6 + suffix
.length () > maxPathLen
)
366 if (suffix
.charAt(0) == '.')
368 suffix
= suffix
.substring(0, suf_len
);
369 if (prefix
.length () + 6 + suf_len
> maxPathLen
)
370 prefix
= prefix
.substring(0, maxPathLen
- 6 - suf_len
);
375 // How many times should we try? We choose 100.
376 for (int i
= 0; i
< 100; ++i
)
379 String t
= "ZZZZZZ" + nextValue ();
380 String l
= prefix
+ t
.substring(t
.length() - 6) + suffix
;
383 f
= new File(directory
, l
);
384 if (f
.createNewFile())
387 catch (IOException ignored
)
392 throw new IOException ("cannot create temporary file");
395 private native boolean performSetReadOnly();
398 public boolean setReadOnly()
401 return performSetReadOnly();
404 private static native File
[] performListRoots();
407 public static File
[] listRoots()
409 File
[] roots
= performListRoots();
411 SecurityManager s
= System
.getSecurityManager();
414 // Only return roots to which the security manager permits read access.
415 int count
= roots
.length
;
416 for (int i
= 0; i
< roots
.length
; i
++)
420 s
.checkRead(roots
[i
].path
);
422 catch (SecurityException sx
)
428 if (count
!= roots
.length
)
430 File
[] newRoots
= new File
[count
];
432 for (int i
=0; i
< roots
.length
; i
++)
434 if (roots
[i
] != null)
435 newRoots
[k
++] = roots
[i
];
443 public static File
createTempFile (String prefix
, String suffix
)
446 return createTempFile (prefix
, suffix
, null);
450 public int compareTo(File other
)
453 return path
.compareTo (other
.path
);
455 return path
.compareToIgnoreCase (other
.path
);
459 public int compareTo(Object o
)
461 File other
= (File
) o
;
462 return compareTo (other
);
465 private native boolean performRenameTo (File dest
);
466 public boolean renameTo (File dest
)
468 SecurityManager s
= System
.getSecurityManager();
469 String sname
= getName();
470 String dname
= dest
.getName();
476 return performRenameTo (dest
);
479 private native boolean performSetLastModified(long time
);
482 public boolean setLastModified(long time
)
485 return performSetLastModified(time
);
488 public static final String pathSeparator
489 = System
.getProperty("path.separator");
490 public static final char pathSeparatorChar
= pathSeparator
.charAt(0);
491 public static final String separator
= System
.getProperty("file.separator");
492 public static final char separatorChar
= separator
.charAt(0);
494 static final String tmpdir
= System
.getProperty("java.io.tmpdir");
495 static int maxPathLen
;
496 static boolean caseSensitive
;
497 static String dupSeparator
= separator
+ separator
;
504 // Native function called at class initialization. This should should
505 // set the maxPathLen and caseSensitive variables.
506 private static native void init_native();
511 // We keep a counter for use by createTempFile. We choose the first
512 // value randomly to try to avoid clashes with other VMs.
513 private static long counter
= Double
.doubleToLongBits (Math
.random ());
515 private void checkWrite ()
517 SecurityManager s
= System
.getSecurityManager();
522 private void checkRead ()
524 SecurityManager s
= System
.getSecurityManager();
530 * Add this File to the set of files to be deleted upon normal
535 // FIXME: This should use the ShutdownHook API once we implement that.
536 public void deleteOnExit ()
538 SecurityManager sm
= System
.getSecurityManager ();
540 sm
.checkDelete (getName ());
542 FileDeleter
.add (this);
545 private void writeObject (ObjectOutputStream oos
) throws IOException
547 oos
.defaultWriteObject ();
548 oos
.writeChar (separatorChar
);
551 private void readObject (ObjectInputStream ois
)
552 throws ClassNotFoundException
, IOException
554 ois
.defaultReadObject ();
556 // If the file was from an OS with a different dir separator,
557 // fixup the path to use the separator on this OS.
558 char oldSeparatorChar
= ois
.readChar ();
559 if (oldSeparatorChar
!= separatorChar
)
560 path
= path
.replace (oldSeparatorChar
, separatorChar
);
563 // QUERY arguments to access function.
564 private final static int READ
= 0;
565 private final static int WRITE
= 1;
566 private final static int EXISTS
= 2;
568 // QUERY arguments to stat function.
569 private final static int DIRECTORY
= 0;
570 private final static int ISFILE
= 1;
571 private final static int ISHIDDEN
= 2;
573 // QUERY arguments to attr function.
574 private final static int MODIFIED
= 0;
575 private final static int LENGTH
= 1;
577 private final native long attr (int query
);
578 // On OSF1 V5.0, `stat' is a macro. It is easiest to use the name
579 // `_stat' instead. We do the same thing for `_access' just in
581 private final native boolean _access (int query
);
582 private final native boolean _stat (int query
);
584 private static final long serialVersionUID
= 301077366599181567L;