mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			1608 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			1608 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			Java
		
	
	
	
/* 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
 |