123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608 |
- /* File.java -- Class representing a file on disk
- Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- GNU Classpath is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- package java.io;
- import gnu.classpath.SystemProperties;
- import gnu.java.lang.CPStringBuilder;
- import java.net.MalformedURLException;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.net.URL;
- /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
- * "The Java Language Specification", ISBN 0-201-63451-1
- * Status: Complete to version 1.3.
- */
- /**
- * This class represents a file or directory on a local disk. It provides
- * facilities for dealing with a variety of systems that use various
- * types of path separators ("/" versus "\", for example). It also
- * contains method useful for creating and deleting files and directories.
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- * @author Tom Tromey (tromey@cygnus.com)
- */
- public class File implements Serializable, Comparable<File>
- {
- private static final long serialVersionUID = 301077366599181567L;
- /**
- * This is the path separator string for the current host. This field
- * contains the value of the <code>file.separator</code> system property.
- * An example separator string would be "/" on the GNU system.
- */
- public static final String separator = SystemProperties.getProperty("file.separator");
- private static final String dupSeparator = separator + separator;
- /**
- * This is the first character of the file separator string. On many
- * hosts (for example, on the GNU system), this represents the entire
- * separator string. The complete separator string is obtained from the
- * <code>file.separator</code>system property.
- */
- public static final char separatorChar = separator.charAt(0);
- /**
- * This is the string that is used to separate the host name from the
- * path name in paths that include the host name. It is the value of
- * the <code>path.separator</code> system property.
- */
- public static final String pathSeparator
- = SystemProperties.getProperty("path.separator");
- /**
- * This is the first character of the string used to separate the host name
- * from the path name in paths that include a host. The separator string
- * is taken from the <code>path.separator</code> system property.
- */
- public static final char pathSeparatorChar = pathSeparator.charAt(0);
- /**
- * This is the path to the file set when the object is created. It
- * may be an absolute or relative path name.
- */
- private String path;
- /**
- * The time (millisecond), when the last temporary file was created.
- */
- private static long last_tmp;
- /**
- * The number of files, created during the current millisecond.
- */
- private static int n_created;
- /**
- * This method tests whether or not the current thread is allowed to
- * to read the file pointed to by this object. This will be true if and
- * and only if 1) the file exists and 2) the <code>SecurityManager</code>
- * (if any) allows access to the file via it's <code>checkRead</code>
- * method 3) the file is readable.
- *
- * @return <code>true</code> if reading is allowed,
- * <code>false</code> otherwise
- *
- * @exception SecurityException If the <code>SecurityManager</code>
- * does not allow access to the file
- */
- public boolean canRead()
- {
- // Test for existence. This also does the SecurityManager check
- if (!exists())
- return false;
- return VMFile.canRead(path);
- }
- /**
- * This method test whether or not the current thread is allowed to
- * write to this object. This will be true if and only if 1) The
- * <code>SecurityManager</code> (if any) allows write access to the
- * file and 2) The file exists and 3) The file is writable. To determine
- * whether or not a non-existent file can be created, check the parent
- * directory for write access.
- *
- * @return <code>true</code> if writing is allowed, <code>false</code>
- * otherwise
- *
- * @exception SecurityException If the <code>SecurityManager</code>
- * does not allow access to the file
- */
- public boolean canWrite()
- {
- // First do a SecurityCheck before doing anything else.
- checkWrite();
- // Test for existence. This is required by the spec
- if (! VMFile.exists(path))
- return false;
- if (VMFile.isDirectory(path))
- return VMFile.canWriteDirectory(path);
- else
- return VMFile.canWrite(path);
- }
- /**
- * This method tests whether or not the current thread is allowed to
- * to execute the file pointed to by this object. This will be true if and
- * and only if 1) the file exists and 2) the <code>SecurityManager</code>
- * (if any) allows access to the file via it's <code>checkExec</code>
- * method 3) the file is executable.
- *
- * @return <code>true</code> if execution is allowed,
- * <code>false</code> otherwise
- *
- * @exception SecurityException If the <code>SecurityManager</code>
- * does not allow access to the file
- */
- public boolean canExecute()
- {
- if (!VMFile.exists(path))
- return false;
- checkExec();
- return VMFile.canExecute(path);
- }
- /**
- * This method creates a new file of zero length with the same name as
- * the path of this <code>File</code> object if an only if that file
- * does not already exist.
- * <p>
- * A <code>SecurityManager.checkWrite</code> check is done prior
- * to performing this action.
- *
- * @return <code>true</code> if the file was created, <code>false</code> if
- * the file alread existed.
- *
- * @exception IOException If an I/O error occurs
- * @exception SecurityException If the <code>SecurityManager</code> will
- * not allow this operation to be performed.
- *
- * @since 1.2
- */
- public boolean createNewFile() throws IOException
- {
- checkWrite();
- return VMFile.create(path);
- }
- /**
- * This method deletes the file represented by this object. If this file
- * is a directory, it must be empty in order for the delete to succeed.
- *
- * @return <code>true</code> if the file was deleted, <code>false</code>
- * otherwise
- *
- * @exception SecurityException If deleting of the file is not allowed
- */
- public synchronized boolean delete()
- {
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkDelete(path);
- return VMFile.delete(path);
- }
- /**
- * This method tests two <code>File</code> objects for equality by
- * comparing the path of the specified <code>File</code> against the path
- * of this object. The two objects are equal if an only if 1) The
- * argument is not null 2) The argument is a <code>File</code> object and
- * 3) The path of the <code>File</code>argument is equal to the path
- * of this object.
- * <p>
- * The paths of the files are determined by calling the
- * <code>getPath()</code>
- * method on each object.
- *
- * @return <code>true</code> if the two objects are equal,
- * <code>false</code> otherwise.
- */
- public boolean equals(Object obj)
- {
- if (! (obj instanceof File))
- return false;
- File other = (File) obj;
- if (VMFile.IS_CASE_SENSITIVE)
- return path.equals(other.path);
- else
- return path.equalsIgnoreCase(other.path);
- }
- /**
- * This method tests whether or not the file represented by the object
- * actually exists on the filesystem.
- *
- * @return <code>true</code> if the file exists, <code>false</code>otherwise.
- *
- * @exception SecurityException If reading of the file is not permitted
- */
- public boolean exists()
- {
- checkRead();
- return VMFile.exists(path);
- }
- /**
- * This method initializes a new <code>File</code> object to represent
- * a file with the specified path.
- *
- * @param name The path name of the file
- */
- public File(String name)
- {
- path = normalizePath (name);
- }
- // Remove duplicate and redundant separator characters.
- private String normalizePath(String p)
- {
- // On Windows, convert any '/' to '\'. This appears to be the same logic
- // that Sun's Win32 Java performs.
- if (separatorChar == '\\')
- {
- p = p.replace ('/', '\\');
- // We have to special case the "\c:" prefix.
- if (p.length() > 2 && p.charAt(0) == '\\' &&
- ((p.charAt(1) >= 'a' && p.charAt(1) <= 'z') ||
- (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z')) &&
- p.charAt(2) == ':')
- p = p.substring(1);
- }
- int dupIndex = p.indexOf(dupSeparator);
- int plen = p.length();
- // Special case: permit Windows UNC path prefix.
- if (dupSeparator.equals("\\\\") && dupIndex == 0)
- dupIndex = p.indexOf(dupSeparator, 1);
- if (dupIndex == -1)
- {
- // Ignore trailing separator (though on Windows "a:\", for
- // example, is a valid and minimal path).
- if (plen > 1 && p.charAt (plen - 1) == separatorChar)
- {
- if (! (separatorChar == '\\' && ((plen == 3 && p.charAt(1) == ':')
- || (plen == 2 && p.charAt(0) == separatorChar))))
- return p.substring (0, plen - 1);
- }
- else
- return p;
- }
- CPStringBuilder newpath = new CPStringBuilder(plen);
- int last = 0;
- while (dupIndex != -1)
- {
- newpath.append(p.substring(last, dupIndex));
- // Ignore the duplicate path characters.
- while (p.charAt(dupIndex) == separatorChar)
- {
- dupIndex++;
- if (dupIndex == plen)
- {
- if ((separatorChar == '\\'
- && newpath.length() == 2
- && newpath.charAt(1) == ':')
- || (separatorChar != '\\' && newpath.length() == 0))
- {
- newpath.append(separatorChar);
- }
- return newpath.toString();
- }
- }
- newpath.append(separatorChar);
- last = dupIndex;
- dupIndex = p.indexOf(dupSeparator, last);
- }
- // Again, ignore possible trailing separator (except special cases
- // like "a:\" on Windows).
- int end;
- if (plen > 1 && p.charAt (plen - 1) == separatorChar)
- {
- if (separatorChar == '\\'
- && ((plen == 3 && p.charAt(1) == ':')
- || (plen == 2 && p.charAt(0) == separatorChar)))
- end = plen;
- else
- end = plen - 1;
- }
- else
- end = plen;
- newpath.append(p.substring(last, end));
- return newpath.toString();
- }
- /**
- * This method initializes a new <code>File</code> object to represent
- * a file in the specified named directory. The path name to the file
- * will be the directory name plus the separator string plus the file
- * name. If the directory path name ends in the separator string, another
- * separator string will still be appended.
- *
- * @param dirPath The path to the directory the file resides in
- * @param name The name of the file
- */
- public File(String dirPath, String name)
- {
- if (name == null)
- throw new NullPointerException();
- if (dirPath != null)
- {
- if (dirPath.length() > 0)
- {
- // Try to be smart about the number of separator characters.
- if (dirPath.charAt(dirPath.length() - 1) == separatorChar
- || name.length() == 0)
- path = normalizePath(dirPath + name);
- else
- path = normalizePath(dirPath + separatorChar + name);
- }
- else
- {
- // If dirPath is empty, use a system dependant
- // default prefix.
- // Note that the leading separators in name have
- // to be chopped off, to prevent them forming
- // a UNC prefix on Windows.
- if (separatorChar == '\\' /* TODO use ON_WINDOWS */)
- {
- int skip = 0;
- while(name.length() > skip
- && (name.charAt(skip) == separatorChar
- || name.charAt(skip) == '/'))
- {
- skip++;
- }
- name = name.substring(skip);
- }
- path = normalizePath(separatorChar + name);
- }
- }
- else
- path = normalizePath(name);
- }
- /**
- * This method initializes a new <code>File</code> object to represent
- * a file in the specified directory. If the <code>directory</code>
- * argument is <code>null</code>, the file is assumed to be in the
- * current directory as specified by the <code>user.dir</code> system
- * property
- *
- * @param directory The directory this file resides in
- * @param name The name of the file
- */
- public File(File directory, String name)
- {
- this (directory == null ? null : directory.path, name);
- }
- /**
- * This method initializes a new <code>File</code> object to represent
- * a file corresponding to the specified <code>file:</code> protocol URI.
- *
- * @param uri The URI
- * @throws IllegalArgumentException if the URI is not hierarchical
- */
- public File(URI uri)
- {
- if (uri == null)
- throw new NullPointerException("uri is null");
- if (!uri.getScheme().equals("file"))
- throw new IllegalArgumentException("invalid uri protocol");
- String name = uri.getPath();
- if (name == null)
- throw new IllegalArgumentException("URI \"" + uri
- + "\" is not hierarchical");
- path = normalizePath(name);
- }
- /**
- * This method returns the path of this file as an absolute path name.
- * If the path name is already absolute, then it is returned. Otherwise
- * the value returned is the current directory plus the separatory
- * string plus the path of the file. The current directory is determined
- * from the <code>user.dir</code> system property.
- *
- * @return The absolute path of this file
- */
- public String getAbsolutePath()
- {
- if (isAbsolute())
- return path;
- else
- return VMFile.getAbsolutePath(path);
- }
- /**
- * This method returns a <code>File</code> object representing the
- * absolute path of this object.
- *
- * @return A <code>File</code> with the absolute path of the object.
- *
- * @since 1.2
- */
- public File getAbsoluteFile()
- {
- return new File(getAbsolutePath());
- }
- /**
- * This method returns a canonical representation of the pathname of
- * this file. The actual form of the canonical representation is
- * system-dependent. On the GNU system, conversion to canonical
- * form involves the removal of redundant separators, references to
- * "." and "..", and symbolic links.
- * <p>
- * Note that this method, unlike the other methods which return path
- * names, can throw an IOException. This is because native method
- * might be required in order to resolve the canonical path
- *
- * @exception IOException If an error occurs
- */
- public String getCanonicalPath() throws IOException
- {
- // On Windows, getAbsolutePath might end up calling us, so we
- // have to special case that call to avoid infinite recursion.
- if (separatorChar == '\\' && path.length() == 2 &&
- ((path.charAt(0) >= 'a' && path.charAt(0) <= 'z') ||
- (path.charAt(0) >= 'A' && path.charAt(0) <= 'Z')) &&
- path.charAt(1) == ':')
- {
- return VMFile.toCanonicalForm(path);
- }
- // Call getAbsolutePath first to make sure that we do the
- // current directory handling, because the native code
- // may have a different idea of the current directory.
- return VMFile.toCanonicalForm(getAbsolutePath());
- }
- /**
- * This method returns a <code>File</code> object representing the
- * canonical path of this object.
- *
- * @return A <code>File</code> instance representing the canonical path of
- * this object.
- *
- * @exception IOException If an error occurs.
- *
- * @since 1.2
- */
- public File getCanonicalFile() throws IOException
- {
- return new File(getCanonicalPath());
- }
- /**
- * This method returns the name of the file. This is everything in the
- * complete path of the file after the last instance of the separator
- * string.
- *
- * @return The file name
- */
- public String getName()
- {
- return VMFile.getName(path);
- }
- /**
- * This method returns a <code>String</code> the represents this file's
- * parent. <code>null</code> is returned if the file has no parent. The
- * parent is determined via a simple operation which removes the name
- * after the last file separator character, as determined by the platform.
- *
- * @return The parent directory of this file
- */
- public String getParent()
- {
- String prefix = null;
- int nameSeqIndex = 0;
- if (path.equals(""))
- return null;
- // The "prefix", if present, is the leading "/" on UNIX and
- // either the drive specifier (e.g. "C:") or the leading "\\"
- // of a UNC network path on Windows.
- if (separatorChar == '/' && path.charAt (0) == '/')
- {
- prefix = "/";
- nameSeqIndex = 1;
- }
- else if (separatorChar == '\\' && path.length() > 1)
- {
- if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
- || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
- || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
- && path.charAt (1) == ':'))
- {
- prefix = path.substring (0, 2);
- nameSeqIndex = 2;
- }
- }
- // According to the JDK docs, the returned parent path is the
- // portion of the name sequence before the last separator
- // character, if found, prefixed by the prefix, otherwise null.
- if (nameSeqIndex < path.length())
- {
- String nameSeq = path.substring (nameSeqIndex, path.length());
- int last = nameSeq.lastIndexOf (separatorChar);
- if (last == -1)
- return prefix;
- else if (last == (nameSeq.length() - 1))
- // Note: The path would not have a trailing separator
- // except for cases like "C:\" on Windows (see
- // normalizePath( )), where Sun's JRE 1.4 returns null.
- return null;
- else if (last == 0)
- last++;
- if (prefix != null)
- return prefix + nameSeq.substring (0, last);
- else
- return nameSeq.substring (0, last);
- }
- else
- // Sun's JRE 1.4 returns null if the prefix is the only
- // component of the path - so "/" gives null on UNIX and
- // "C:", "\\", etc. return null on Windows.
- return null;
- }
- /**
- * This method returns a <code>File</code> object representing the parent
- * file of this one.
- *
- * @return a <code>File</code> for the parent of this object.
- * <code>null</code>
- * will be returned if this object does not have a parent.
- *
- * @since 1.2
- */
- public File getParentFile()
- {
- String parent = getParent();
- return parent != null ? new File(parent) : null;
- }
- /**
- * Returns the path name that represents this file. May be a relative
- * or an absolute path name
- *
- * @return The pathname of this file
- */
- public String getPath()
- {
- return path;
- }
- /**
- * This method returns a hash code representing this file. It is the
- * hash code of the path of this file (as returned by <code>getPath()</code>)
- * exclusived or-ed with the value 1234321.
- *
- * @return The hash code for this object
- */
- public int hashCode()
- {
- if (VMFile.IS_CASE_SENSITIVE)
- return path.hashCode() ^ 1234321;
- else
- return path.toLowerCase().hashCode() ^ 1234321;
- }
- /**
- * This method returns true if this object represents an absolute file
- * path and false if it does not. The definition of an absolute path varies
- * by system. As an example, on GNU systems, a path is absolute if it starts
- * with a "/".
- *
- * @return <code>true</code> if this object represents an absolute
- * file name, <code>false</code> otherwise.
- */
- public boolean isAbsolute()
- {
- return VMFile.isAbsolute(path);
- }
- /**
- * This method tests whether or not the file represented by this object
- * is a directory. In order for this method to return <code>true</code>,
- * the file represented by this object must exist and be a directory.
- *
- * @return <code>true</code> if this file is a directory, <code>false</code>
- * otherwise
- *
- * @exception SecurityException If reading of the file is not permitted
- */
- public boolean isDirectory()
- {
- checkRead();
- return VMFile.isDirectory(path);
- }
- /**
- * This method tests whether or not the file represented by this object
- * is a "plain" file. A file is a plain file if and only if it 1) Exists,
- * 2) Is not a directory or other type of special file.
- *
- * @return <code>true</code> if this is a plain file, <code>false</code>
- * otherwise
- *
- * @exception SecurityException If reading of the file is not permitted
- */
- public boolean isFile()
- {
- checkRead();
- return VMFile.isFile(path);
- }
- /**
- * This method tests whether or not this file represents a "hidden" file.
- * On GNU systems, a file is hidden if its name begins with a "."
- * character. Files with these names are traditionally not shown with
- * directory listing tools.
- *
- * @return <code>true</code> if the file is hidden, <code>false</code>
- * otherwise.
- * @throws SecurityException if a security manager exists and denies
- * read access to this file.
- * @since 1.2
- */
- public boolean isHidden()
- {
- checkRead();
- return VMFile.isHidden(path);
- }
- /**
- * This method returns the last modification time of this file. The
- * time value returned is an abstract value that should not be interpreted
- * as a specified time value. It is only useful for comparing to other
- * such time values returned on the same system. In that case, the larger
- * value indicates a more recent modification time.
- * <p>
- * If the file does not exist, then a value of 0 is returned.
- *
- * @return The last modification time of the file
- *
- * @exception SecurityException If reading of the file is not permitted
- */
- public long lastModified()
- {
- checkRead();
- return VMFile.lastModified(path);
- }
- /**
- * This method returns the length of the file represented by this object,
- * or 0 if the specified file does not exist.
- *
- * @return The length of the file
- *
- * @exception SecurityException If reading of the file is not permitted
- */
- public long length()
- {
- checkRead();
- return VMFile.length(path);
- }
- /**
- * This method returns a array of <code>String</code>'s representing the
- * list of files is then directory represented by this object. If this
- * object represents a non-directory file or a non-existent file, then
- * <code>null</code> is returned. The list of files will not contain
- * any names such as "." or ".." which indicate the current or parent
- * directory. Also, the names are not guaranteed to be sorted.
- * <p>
- * In this form of the <code>list()</code> method, a filter is specified
- * that allows the caller to control which files are returned in the
- * list. The <code>FilenameFilter</code> specified is called for each
- * file returned to determine whether or not that file should be included
- * in the list.
- * <p>
- * A <code>SecurityManager</code> check is made prior to reading the
- * directory. If read access to the directory is denied, an exception
- * will be thrown.
- *
- * @param filter An object which will identify files to exclude from
- * the directory listing.
- *
- * @return An array of files in the directory, or <code>null</code>
- * if this object does not represent a valid directory.
- *
- * @exception SecurityException If read access is not allowed to the
- * directory by the <code>SecurityManager</code>
- */
- public String[] list(FilenameFilter filter)
- {
- checkRead();
- if (!exists() || !isDirectory())
- return null;
- // Get the list of files
- String files[] = VMFile.list(path);
- // Check if an error occured in listInternal().
- // This is an unreadable directory, pretend there is nothing inside.
- if (files == null)
- return new String[0];
- if (filter == null)
- return files;
- // Apply the filter
- int count = 0;
- for (int i = 0; i < files.length; i++)
- {
- if (filter.accept(this, files[i]))
- ++count;
- else
- files[i] = null;
- }
- String[] retfiles = new String[count];
- count = 0;
- for (int i = 0; i < files.length; i++)
- if (files[i] != null)
- retfiles[count++] = files[i];
- return retfiles;
- }
- /**
- * This method returns a array of <code>String</code>'s representing the
- * list of files is then directory represented by this object. If this
- * object represents a non-directory file or a non-existent file, then
- * <code>null</code> is returned. The list of files will not contain
- * any names such as "." or ".." which indicate the current or parent
- * directory. Also, the names are not guaranteed to be sorted.
- * <p>
- * A <code>SecurityManager</code> check is made prior to reading the
- * directory. If read access to the directory is denied, an exception
- * will be thrown.
- *
- * @return An array of files in the directory, or <code>null</code> if
- * this object does not represent a valid directory.
- *
- * @exception SecurityException If read access is not allowed to the
- * directory by the <code>SecurityManager</code>
- */
- public String[] list()
- {
- return list(null);
- }
- /**
- * This method returns an array of <code>File</code> objects representing
- * all the files in the directory represented by this object. If this
- * object does not represent a directory, <code>null</code> is returned.
- * Each of the returned <code>File</code> object is constructed with this
- * object as its parent.
- * <p>
- * A <code>SecurityManager</code> check is made prior to reading the
- * directory. If read access to the directory is denied, an exception
- * will be thrown.
- *
- * @return An array of <code>File</code> objects for this directory.
- *
- * @exception SecurityException If the <code>SecurityManager</code> denies
- * access to this directory.
- *
- * @since 1.2
- */
- public File[] listFiles()
- {
- return listFiles((FilenameFilter) null);
- }
- /**
- * This method returns an array of <code>File</code> objects representing
- * all the files in the directory represented by this object. If this
- * object does not represent a directory, <code>null</code> is returned.
- * Each of the returned <code>File</code> object is constructed with this
- * object as its parent.
- * <p>
- * In this form of the <code>listFiles()</code> method, a filter is specified
- * that allows the caller to control which files are returned in the
- * list. The <code>FilenameFilter</code> specified is called for each
- * file returned to determine whether or not that file should be included
- * in the list.
- * <p>
- * A <code>SecurityManager</code> check is made prior to reading the
- * directory. If read access to the directory is denied, an exception
- * will be thrown.
- *
- * @return An array of <code>File</code> objects for this directory.
- *
- * @exception SecurityException If the <code>SecurityManager</code> denies
- * access to this directory.
- *
- * @since 1.2
- */
- public File[] listFiles(FilenameFilter filter)
- {
- String[] filelist = list(filter);
- if (filelist == null)
- return null;
- File[] fobjlist = new File [filelist.length];
- for (int i = 0; i < filelist.length; i++)
- fobjlist [i] = new File(this, filelist [i]);
- return fobjlist;
- }
- /**
- * This method returns an array of <code>File</code> objects representing
- * all the files in the directory represented by this object. If this
- * object does not represent a directory, <code>null</code> is returned.
- * Each of the returned <code>File</code> object is constructed with this
- * object as its parent.
- * <p>
- * In this form of the <code>listFiles()</code> method, a filter is specified
- * that allows the caller to control which files are returned in the
- * list. The <code>FileFilter</code> specified is called for each
- * file returned to determine whether or not that file should be included
- * in the list.
- * <p>
- * A <code>SecurityManager</code> check is made prior to reading the
- * directory. If read access to the directory is denied, an exception
- * will be thrown.
- *
- * @return An array of <code>File</code> objects for this directory.
- *
- * @exception SecurityException If the <code>SecurityManager</code> denies
- * access to this directory.
- *
- * @since 1.2
- */
- public File[] listFiles(FileFilter filter)
- {
- File[] fobjlist = listFiles((FilenameFilter) null);
- if (fobjlist == null)
- return null;
- if (filter == null)
- return fobjlist;
- int count = 0;
- for (int i = 0; i < fobjlist.length; i++)
- if (filter.accept(fobjlist[i]) == true)
- ++count;
- File[] final_list = new File[count];
- count = 0;
- for (int i = 0; i < fobjlist.length; i++)
- if (filter.accept(fobjlist[i]) == true)
- {
- final_list[count] = fobjlist[i];
- ++count;
- }
- return final_list;
- }
- /**
- * This method returns a <code>String</code> that is the path name of the
- * file as returned by <code>getPath</code>.
- *
- * @return A <code>String</code> representation of this file
- */
- public String toString()
- {
- return path;
- }
- /**
- * @return A <code>URI</code> for this object.
- */
- public URI toURI()
- {
- String abspath = getAbsolutePath();
- if (isDirectory() || path.equals(""))
- abspath = abspath + separatorChar;
- if (separatorChar == '\\')
- abspath = separatorChar + abspath;
- try
- {
- return new URI("file", null, null, -1,
- abspath.replace(separatorChar, '/'),
- null, null);
- }
- catch (URISyntaxException use)
- {
- // Can't happen.
- throw (InternalError) new InternalError("Unconvertible file: "
- + this).initCause(use);
- }
- }
- /**
- * This method returns a <code>URL</code> with the <code>file:</code>
- * protocol that represents this file. The exact form of this URL is
- * system dependent.
- *
- * @return A <code>URL</code> for this object.
- *
- * @exception MalformedURLException If the URL cannot be created
- * successfully.
- */
- public URL toURL() throws MalformedURLException
- {
- return VMFile.toURL(this);
- }
- /**
- * This method creates a directory for the path represented by this object.
- *
- * @return <code>true</code> if the directory was created,
- * <code>false</code> otherwise
- *
- * @exception SecurityException If write access is not allowed to this file
- */
- public boolean mkdir()
- {
- checkWrite();
- return VMFile.mkdir(path);
- }
- /**
- * This method creates a directory for the path represented by this file.
- * It will also create any intervening parent directories if necessary.
- *
- * @return <code>true</code> if the directory was created,
- * <code>false</code> otherwise
- *
- * @exception SecurityException If write access is not allowed to this file
- */
- public boolean mkdirs()
- {
- String parent = getParent();
- if (parent == null)
- {
- return mkdir();
- }
- File f = new File(parent);
- if (!f.exists())
- {
- boolean rc = f.mkdirs();
- if (rc == false)
- return false;
- }
- return mkdir();
- }
- /**
- * This method creates a temporary file in the specified directory. If
- * the directory name is null, then this method uses the system temporary
- * directory. The files created are guaranteed not to currently exist and
- * the same file name will never be used twice in the same virtual
- * machine instance.
- * The system temporary directory is determined by examinging the
- * <code>java.io.tmpdir</code> system property.
- * <p>
- * The <code>prefix</code> parameter is a sequence of at least three
- * characters that are used as the start of the generated filename. The
- * <code>suffix</code> parameter is a sequence of characters that is used
- * to terminate the file name. This parameter may be <code>null</code>
- * and if it is, the suffix defaults to ".tmp".
- * <p>
- * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
- * method is used to verify that this operation is permitted.
- *
- * @param prefix The character prefix to use in generating the path name.
- * @param suffix The character suffix to use in generating the path name.
- * @param directory The directory to create the file in, or
- * <code>null</code> for the default temporary directory
- *
- * @exception IllegalArgumentException If the patterns is not valid
- * @exception SecurityException If there is no permission to perform
- * this operation
- * @exception IOException If an error occurs
- *
- * @since 1.2
- */
- public static synchronized File createTempFile(String prefix, String suffix,
- File directory)
- throws IOException
- {
- // Grab the system temp directory if necessary
- if (directory == null)
- {
- String dirname = System.getProperty("java.io.tmpdir");
- if (dirname == null)
- throw new IOException("Cannot determine system temporary directory");
- directory = new File(dirname);
- if (! VMFile.exists(directory.path))
- throw new IOException("System temporary directory "
- + directory.getName() + " does not exist.");
- if (! VMFile.isDirectory(directory.path))
- throw new IOException("System temporary directory "
- + directory.getName()
- + " is not really a directory.");
- }
- // Check if prefix is at least 3 characters long
- if (prefix.length() < 3)
- throw new IllegalArgumentException("Prefix too short: " + prefix);
- // Set default value of suffix
- if (suffix == null)
- suffix = ".tmp";
- // Now identify a file name and make sure it doesn't exist.
- File file;
- if (!VMFile.IS_DOS_8_3)
- {
- do
- {
- long now = System.currentTimeMillis();
- if (now > last_tmp)
- {
- // The last temporary file was created more than 1 ms ago.
- last_tmp = now;
- n_created = 0;
- }
- else
- n_created++;
- String name = Long.toHexString(now);
- if (n_created > 0)
- name += '_'+Integer.toHexString(n_created);
- String filename = prefix + name + suffix;
- file = new File(directory, filename);
- }
- while (VMFile.exists(file.path));
- }
- else
- {
- // make sure prefix is not longer than 7 characters
- if (prefix.length() >= 8)
- throw new IllegalArgumentException("Prefix too long: " + prefix + "(valid length 3..7)");
- long mask = 0x000000ffffFFFFL >> (prefix.length() * 4);
- do
- {
- int n = (int) (System.currentTimeMillis() & mask);
- String filename = prefix + java.lang.Integer.toHexString(n) + suffix;
- file = new File(directory, filename);
- }
- while (VMFile.exists(file.path));
- }
- // Verify that we are allowed to create this file
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkWrite(file.getAbsolutePath());
- // Now create the file and return our file object
- // XXX - FIXME race condition.
- VMFile.create(file.getAbsolutePath());
- return file;
- }
- /**
- * This method sets the owner's read permission for the File represented by
- * this object.
- *
- * It is the same as calling <code>setReadable(readable, true)</code>.
- *
- * @param <code>readable</code> <code>true</code> to set read permission,
- * <code>false</code> to unset the read permission.
- * @return <code>true</code> if the file permissions are changed,
- * <code>false</code> otherwise.
- * @exception SecurityException If write access of the file is not permitted.
- * @see #setReadable(boolean, boolean)
- * @since 1.6
- */
- public boolean setReadable(boolean readable)
- {
- return setReadable(readable, true);
- }
- /**
- * This method sets the read permissions for the File represented by
- * this object.
- *
- * If <code>ownerOnly</code> is set to <code>true</code> then only the
- * read permission bit for the owner of the file is changed.
- *
- * If <code>ownerOnly</code> is set to <code>false</code>, the file
- * permissions are changed so that the file can be read by everyone.
- *
- * On unix like systems this sets the <code>user</code>, <code>group</code>
- * and <code>other</code> read bits and is equal to call
- * <code>chmod a+r</code> on the file.
- *
- * @param <code>readable</code> <code>true</code> to set read permission,
- * <code>false</code> to unset the read permission.
- * @param <code>ownerOnly</code> <code>true</code> to set read permission
- * for owner only, <code>false</code> for all.
- * @return <code>true</code> if the file permissions are changed,
- * <code>false</code> otherwise.
- * @exception SecurityException If write access of the file is not permitted.
- * @see #setReadable(boolean)
- * @since 1.6
- */
- public boolean setReadable(boolean readable, boolean ownerOnly)
- {
- checkWrite();
- return VMFile.setReadable(path, readable, ownerOnly);
- }
- /**
- * This method sets the owner's write permission for the File represented by
- * this object.
- *
- * It is the same as calling <code>setWritable(readable, true)</code>.
- *
- * @param <code>writable</code> <code>true</code> to set write permission,
- * <code>false</code> to unset write permission.
- * @return <code>true</code> if the file permissions are changed,
- * <code>false</code> otherwise.
- * @exception SecurityException If write access of the file is not permitted.
- * @see #setWritable(boolean, boolean)
- * @since 1.6
- */
- public boolean setWritable(boolean writable)
- {
- return setWritable(writable, true);
- }
- /**
- * This method sets the write permissions for the File represented by
- * this object.
- *
- * If <code>ownerOnly</code> is set to <code>true</code> then only the
- * write permission bit for the owner of the file is changed.
- *
- * If <code>ownerOnly</code> is set to <code>false</code>, the file
- * permissions are changed so that the file can be written by everyone.
- *
- * On unix like systems this set the <code>user</code>, <code>group</code>
- * and <code>other</code> write bits and is equal to call
- * <code>chmod a+w</code> on the file.
- *
- * @param <code>writable</code> <code>true</code> to set write permission,
- * <code>false</code> to unset write permission.
- * @param <code>ownerOnly</code> <code>true</code> to set write permission
- * for owner only, <code>false</code> for all.
- * @return <code>true</code> if the file permissions are changed,
- * <code>false</code> otherwise.
- * @exception SecurityException If write access of the file is not permitted.
- * @see #setWritable(boolean)
- * @since 1.6
- */
- public boolean setWritable(boolean writable, boolean ownerOnly)
- {
- checkWrite();
- return VMFile.setWritable(path, writable, ownerOnly);
- }
- /**
- * This method sets the owner's execute permission for the File represented
- * by this object.
- *
- * It is the same as calling <code>setExecutable(readable, true)</code>.
- *
- * @param <code>executable</code> <code>true</code> to set execute permission,
- * <code>false</code> to unset execute permission.
- * @return <code>true</code> if the file permissions are changed,
- * <code>false</code> otherwise.
- * @exception SecurityException If write access of the file is not permitted.
- * @see #setExecutable(boolean, boolean)
- * @since 1.6
- */
- public boolean setExecutable(boolean executable)
- {
- return setExecutable(executable, true);
- }
- /**
- * This method sets the execute permissions for the File represented by
- * this object.
- *
- * If <code>ownerOnly</code> is set to <code>true</code> then only the
- * execute permission bit for the owner of the file is changed.
- *
- * If <code>ownerOnly</code> is set to <code>false</code>, the file
- * permissions are changed so that the file can be executed by everyone.
- *
- * On unix like systems this set the <code>user</code>, <code>group</code>
- * and <code>other</code> write bits and is equal to call
- * <code>chmod a+x</code> on the file.
- *
- * @param <code>executable</code> <code>true</code> to set write permission,
- * <code>false</code> to unset write permission.
- * @param <code>ownerOnly</code> <code>true</code> to set write permission
- * for owner only, <code>false</code> for all.
- * @return <code>true</code> if the file permissions are changed,
- * <code>false</code> otherwise.
- * @exception SecurityException If write access of the file is not permitted.
- * @see #setExecutable(boolean)
- * @since 1.6
- */
- public boolean setExecutable(boolean executable, boolean ownerOnly)
- {
- checkWrite();
- return VMFile.setExecutable(path, executable, ownerOnly);
- }
- /**
- * Get the total space for the partition pointed by this file path, in bytes.
- *
- * @return the total number of bytes in this partition.
- * @since 1.6
- */
- public long getTotalSpace()
- {
- // check security manager.
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkPermission(new RuntimePermission("getFileSystemAttributes"));
- checkRead();
- return VMFile.getTotalSpace(path);
- }
- /**
- * Get the free space in the partition pointed by this file path, in bytes.
- *
- * @return the number of free bytes in this partition.
- * @since 1.6
- */
- public long getFreeSpace()
- {
- // check security manager.
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkPermission(new RuntimePermission("getFileSystemAttributes"));
- checkRead();
- return VMFile.getFreeSpace(path);
- }
- /**
- * Get the usable space in the partition pointed by this file path, in bytes.
- * This is not necessarily the same as the number returned by
- * {@link #getFreeSpace()}.
- *
- * <strong>Implementation note</strong>: Unlike the RI, on Linux and UNIX
- * like systems this methods take into account the reserved space for the
- * "root" user. This means that the returned results will be a little
- * different if a normal user or root perform the query.
- *
- * Also, the bytes returned should be interpreted as an hint, and may be
- * different at each call of this method or even right after the method
- * returns.
- *
- * @return the number of usable bytes in this partition.
- * @since 1.6
- */
- public long getUsableSpace()
- {
- // check security manager.
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkPermission(new RuntimePermission("getFileSystemAttributes"));
- checkRead();
- // root users can use the reserved extra space
- String user = System.getProperty("user.name");
- if (user != null && user.equals("root"))
- return VMFile.getFreeSpace(path);
- return VMFile.getUsableSpace(path);
- }
- /**
- * This method sets the file represented by this object to be read only.
- * A read only file or directory cannot be modified. Please note that
- * GNU systems allow read only files to be deleted if the directory it
- * is contained in is writable.
- *
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * otherwise.
- *
- * @exception SecurityException If the <code>SecurityManager</code> does
- * not allow this operation.
- *
- * @since 1.2
- */
- public boolean setReadOnly()
- {
- // Do a security check before trying to do anything else.
- checkWrite();
- // Test for existence.
- if (! VMFile.exists(path))
- return false;
- return VMFile.setReadOnly(path);
- }
- /**
- * This method returns an array of filesystem roots. Some operating systems
- * have volume oriented filesystem. This method provides a mechanism for
- * determining which volumes exist. GNU systems use a single hierarchical
- * filesystem, so will have only one "/" filesystem root.
- *
- * @return An array of <code>File</code> objects for each filesystem root
- * available.
- *
- * @since 1.2
- */
- public static File[] listRoots()
- {
- File[] roots = VMFile.listRoots();
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- {
- // Only return roots to which the security manager permits read access.
- int count = roots.length;
- for (int i = 0; i < roots.length; i++)
- {
- try
- {
- s.checkRead (roots[i].path);
- }
- catch (SecurityException sx)
- {
- roots[i] = null;
- count--;
- }
- }
- if (count != roots.length)
- {
- File[] newRoots = new File[count];
- int k = 0;
- for (int i = 0; i < roots.length; i++)
- {
- if (roots[i] != null)
- newRoots[k++] = roots[i];
- }
- roots = newRoots;
- }
- }
- return roots;
- }
- /**
- * This method creates a temporary file in the system temporary directory.
- * The files created are guaranteed not to currently exist and the same file
- * name will never be used twice in the same virtual machine instance. The
- * system temporary directory is determined by examinging the
- * <code>java.io.tmpdir</code> system property.
- * <p>
- * The <code>prefix</code> parameter is a sequence of at least three
- * characters that are used as the start of the generated filename. The
- * <code>suffix</code> parameter is a sequence of characters that is used
- * to terminate the file name. This parameter may be <code>null</code>
- * and if it is, the suffix defaults to ".tmp".
- * <p>
- * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
- * method is used to verify that this operation is permitted.
- * <p>
- * This method is identical to calling
- * <code>createTempFile(prefix, suffix, null)</code>.
- *
- * @param prefix The character prefix to use in generating the path name.
- * @param suffix The character suffix to use in generating the path name.
- *
- * @exception IllegalArgumentException If the prefix or suffix are not valid.
- * @exception SecurityException If there is no permission to perform
- * this operation
- * @exception IOException If an error occurs
- */
- public static File createTempFile(String prefix, String suffix)
- throws IOException
- {
- return createTempFile(prefix, suffix, null);
- }
- /**
- * This method compares the specified <code>File</code> to this one
- * to test for equality. It does this by comparing the canonical path names
- * of the files.
- * <p>
- * The canonical paths of the files are determined by calling the
- * <code>getCanonicalPath</code> method on each object.
- * <p>
- * This method returns a 0 if the specified <code>Object</code> is equal
- * to this one, a negative value if it is less than this one
- * a positive value if it is greater than this one.
- *
- * @return An integer as described above
- *
- * @since 1.2
- */
- public int compareTo(File other)
- {
- if (VMFile.IS_CASE_SENSITIVE)
- return path.compareTo (other.path);
- else
- return path.compareToIgnoreCase (other.path);
- }
- /**
- * This method renames the file represented by this object to the path
- * of the file represented by the argument <code>File</code>.
- *
- * @param dest The <code>File</code> object representing the target name
- *
- * @return <code>true</code> if the rename succeeds, <code>false</code>
- * otherwise.
- *
- * @exception SecurityException If write access is not allowed to the
- * file by the <code>SecurityMananger</code>.
- */
- public synchronized boolean renameTo(File dest)
- {
- checkWrite();
- dest.checkWrite();
- // Call our native rename method
- return VMFile.renameTo(path, dest.path);
- }
- /**
- * This method sets the modification time on the file to the specified
- * value. This is specified as the number of seconds since midnight
- * on January 1, 1970 GMT.
- *
- * @param time The desired modification time.
- *
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * otherwise.
- *
- * @exception IllegalArgumentException If the specified time is negative.
- * @exception SecurityException If the <code>SecurityManager</code> will
- * not allow this operation.
- *
- * @since 1.2
- */
- public boolean setLastModified(long time)
- {
- if (time < 0)
- throw new IllegalArgumentException("Negative modification time: " + time);
- checkWrite();
- return VMFile.setLastModified(path, time);
- }
- private void checkWrite()
- {
- // Check the SecurityManager
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkWrite(path);
- }
- private void checkRead()
- {
- // Check the SecurityManager
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkRead(path);
- }
- private void checkExec()
- {
- // Check the SecurityManager
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkExec(path);
- }
- /**
- * Calling this method requests that the file represented by this object
- * be deleted when the virtual machine exits. Note that this request cannot
- * be cancelled. Also, it will only be carried out if the virtual machine
- * exits normally.
- *
- * @exception SecurityException If deleting of the file is not allowed
- *
- * @since 1.2
- */
- public void deleteOnExit()
- {
- // Check the SecurityManager
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkDelete(path);
- DeleteFileHelper.add(this);
- }
- private void writeObject(ObjectOutputStream oos) throws IOException
- {
- oos.defaultWriteObject();
- oos.writeChar(separatorChar);
- }
- private void readObject(ObjectInputStream ois)
- throws ClassNotFoundException, IOException
- {
- ois.defaultReadObject();
- // If the file was from an OS with a different dir separator,
- // fixup the path to use the separator on this OS.
- char oldSeparatorChar = ois.readChar();
- if (oldSeparatorChar != separatorChar)
- path = path.replace(oldSeparatorChar, separatorChar);
- }
- } // class File
|