File - a classe File

Email que recebi hoje da SUN: tutorial simples de como trabalhar com a classe File.

 

Working With the File Class

The filing system is one of the most basic services that an operating system provides to applications. Historically, it was one of the very first services to be developed. During the 1950s, the ability of a computer to automatically locate and load a program into its memory was not something computer programmers could take for granted.

 

Today, all filing systems allow a hierarchical directory structure of arbitrary depth to organize files of almost equally arbitrary length (4 GB is a common limit per file). File names identify files and are usually limited to anywhere from 32 to 256 characters in length. Although all filing systems are essentially identical in terms of these basic services, their exact implementations make them mutually incompatible.

 

To shield applications from this incompatibility obstacle, the File class defines platform-independent methods for manipulating a file maintained by a native filing system.

 

- File()            Constructs a File object

 

- canRead()

  canWrite()            Returns indication of whether file is readable or writable

 

- compareTo()            Checks for ordering between file paths

 

- createNewFile()            Creates empty file if nonexistent

 

- createTempFile()            Creates empty file in special directory

 

delete()            Removes file from file system

 

- deleteOnExit()            Causes file to be removed from file system when program ends without error

 

- equals()            Checks for equality between file objects (not contents)

 

- exists()            Returns indication of whether file exists

 

- getAbsoluteFile()

  getAbsolutePath()    Returns complete path to file

 

- getCanonicalFile()

  getCanonicalPath()         Returns complete path to file with no relative indicators

 

- getName()            Returns name of file

 

- getParent()

  getParentFile()            Returns parent directory for file

 

- getPath()            Returns file as a potentially relative path

 

- hashCode()            Returns hash code for file

 

- isAbsolute()

  isDirectory()

  isFile()

  isHidden()            Returns indicator status for file type

 

- lastModified()            Returns last modified timestamp

 

- length()            Returns size of file

 

- list()

  listFiles()            Returns list of files and directories in file

 

- listRoots()            Returns list of root filesystems

 

- mkdir()            Creates directory named by file

 

- mkdirs()            Creates directory and complete path as necessary named by file

 

- renameTo()            Renames files

 

- setLastModified()            Changes last modified timestamp

 

- setReadOnly()            Changes file to read-only

 

- toString()            Returns string representation of file state

 

- toURI()

  toURL()            Constructs URI/URL for file

 

As you can see from the list of supported methods, class File does not allow you to access the file's contents. There are no read() or write() methods of File to let you do this. Class File primarily names files, queries file attributes, and manipulates directories or temporary files, all in a system-independent way. The following is a description of what you can do with files without opening them.

 

First off is the toURL() method. Don't use it. With version 6 of the Java Platform, Standard Edition (Java SE, formerly referred to as J2SE), the method becomes deprecated. Stop using it now. Basically, it doesn't properly escape characters that are illegal in URLs. Instead, if you need a URL, first get the URI, then convert the URI to a URL, as in fileVariable.toURI().toURL().

 

Naming Files

 

Files are named in one of two ways. You can either provide both a directory and a file within the directory, or you can provide both combined into one value. Either way, you are providing the full name of a file you wish to access. The benefit of providing a directory and file name separately is that you don't have to worry about how to combine the two. For instance, on Microsoft Windows-based platforms, the separator character is the backward slash character (\). On UNIX platforms, it is the foreward slash character (/). Although you can ask the File class what the separator character is through the separator class variable, you can now save yourself the bother of combining the two terms because the constructor of the File class can do it for you.

 

To demonstrate, the following code fragment attempts to create three File objects. Each line does succeed in creating a File object. However, if you try to use the File object, only the second or third attempts will succeed on all platforms, because they do not have a file separator value hard-coded into the source code.

 

  File f1 = new File("sun/microsystems");

  File f2 = new File("sun""microsystems");

  File f3 = new File(new File("sun"), "microsystems");

 

Querying File Attributes

 

Class File provides a handful of methods for querying a minimal set of file attributes:

 

   * Whether the file exists

   * Whether the file is read protected

   * Whether the file is write protected

   * Whether the file is, in fact, a directory

   * Whether the file is hidden

   * Whether the file is specified as an absolute location

 

Discovering other common file attributes, such as whether a file is a system or an archived file, is not supported. As they did with the Java platform's AWT classes, the designers of these classes have taken the least common denominator of all filing systems for their model. If Java technology included features (such as an archived attribute) that some systems did not support, its universal compatibility across platforms would be jeopardized.

 

The following program shows how to use a File instance to query a

file's attributes. The file is specified as a command-line parameter:

 

import java.io.*;

public class Attr {

  public static void main (String args[]) {

    File path = new File(args[0]);  // grab command-line argument

    String exists   = getYesNo(path.exists());

    String canRead  = getYesNo(path.canRead());

    String canWrite = getYesNo(path.canWrite());

    String isFile   = getYesNo(path.isFile());

    String isHid    = getYesNo(path.isHidden());

    String isDir    = getYesNo(path.isDirectory());

    String isAbs    = getYesNo(path.isAbsolute());

    System.out.println("File attributes for '" + args[0] + "'");

    System.out.println("Exists        : " + exists);

    if (path.exists()) {

      System.out.println("Readable      : " + canRead);

      System.out.println("Writable      : " + canWrite);

      System.out.println("Is directory  : " + isDir);

      System.out.println("Is file       : " + isFile);

      System.out.println("Is hidden     : " + isHid);

      System.out.println("Absolute path : " + isAbs);

    }

  }

  private static String getYesNo(boolean b) {

    return (b ? "Yes" : "No");

  }

 

}

 

You can experiment with this program by passing it various file names and directory names, either relative or absolute. An absolute file name

would be one that started at the root level of the file system, such as C:\. Of course, although C:\ is absolute, it is not a file. The path of the directory at that level would be C:\., where the dot (.) specifies the directory file.

 

With J2SE 5.0, you can set only the readable attribute. Java SE 6 exposes the writable and executable attributes as well.

 

Manipulating Directories

 

A handier program would be one that could list the contents of a directory, as the dir or ls commands do in most operating systems. Fortunately, class File supports directory-list generation through its list() and listFiles() methods. Here's another program that recursively (that is, calling upon itself) lists directories and their contents:

 

import java.io.*;

import java.util.*;

public class Dir {

  static int indentLevel = -1;

  static void listPath(File path) {

    File files[];  // list of files in a directory

    indentLevel++; // going down...

    // Create list of files in this dir.

    files = path.listFiles();

    // Sort with help of Collections API.

    Arrays.sort(files);

    for (int i=0, n=files.length; i < n; i++) {

      for (int indent=0; indent < indentLevel; indent++) {

        System.out.print("    ");

      }

      System.out.println(files[i].toString());

      if (files[i].isDirectory()) {

        // Recursively descend dir tree.

        listPath(files[i]);

      }

    }

    indentLevel--; // And going up

  }

  public static void main (String args[]) {

    listPath(new File(args[0]));

  }

 

}

 

The program relies on a couple of interesting concepts. First of all, it calls itself recursively in the statement listPath(files[i]). This repeated invocation of the listPath() method restarts listPath() with a new path, initialized to contain the deeper directory to list.

 

The directory listing is sorted with the help of the Arrays class. By default, entries in a directory are unordered. To highlight the current directory level, the contents of a directory are indented according to its nesting level in the filing hierarchy. The depth of the recursion level, tracked in the class variable indentLevel, determines this nesting level. When a method exits, class variables are not destroyed the way simple method variables are. The program relies on this behavior to track the recursion level across multiple invocations of listPath().

 

Manipulating Temporary Files

 

One nice feature of the File class is its support for temporary files. Thanks to the static createTempFile() methods and the java.io.tmpdir system property, you can guarantee that the File object created by the method did not previously exist. Also, by calling deleteOnExit(), you can ensure that the file will be deleted if the Java environment ends naturally. The general framework for usage follows:

 

  File temp = File.createTempFile("sun"".tmp"); // Prefix and suffix

  temp.deleteOnExit();

  // Use like any other File.

 

Summary

 

That's really all there is to File in J2SE 5.0. Java SE 6 adds a few

more features such as getting free and total space on a disk partition,

but functionally, the class never opens a file directly. It just

accesses and manipulates the directory information.