6.2.  Use the Files class to check, delete, copy, or move a file or directory

[Note]

The java.nio.file.Files class consists of static methods that use Path objects to work with files and directories.

With file I/O, unexpected conditions are a fact of life: a file exists (or doesn't exist) when expected, the program does not have access to the file system, the default file system implementation does not support a particular function, and so on. All methods that access the file system can throw an IOException. It is best practice to catch these exceptions by embedding these methods into a try-with-resources statement, introduced in the Java SE 7 release.

In addition to IOException, many specific exceptions extend FileSystemException. This class has some useful methods that return the file involved (getFile), the detailed message string (getMessage), the reason why the file system operation failed (getReason), and the "other" file involved, if any (getOtherFile).

Several Files methods accept an arbitrary number of arguments when flags are specified. For example, in the following method signature, the ellipses notation after the CopyOption argument indicates that the method accepts a variable number of arguments, or varargs, as they are typically called:

Files.move(Path, Path, CopyOption...);
					

When a method accepts a varargs argument, you can pass it a comma-separated list of values or an array (CopyOption[]) of values:

import static java.nio.file.StandardCopyOption.*;
...
Path source = ...;
Path target = ...;
Files.move(source, target, REPLACE_EXISTING, ATOMIC_MOVE);
					

Copy a file

To copy one file to another you would use the Files.copy method:

Files.copy(Path source, Path target, CopyOption... options);
					

The options argument are enums that specify how the file should be copied. There are actually two different Enum classes, LinkOption and StandardCopyOption, but both implement the CopyOption interface.

Here is the list of available options for Files.copy:

There is also a StandardCopyOption.ATOMIC_MOVE enum, but if this option is specified, an UsupportedOperationException is thrown. If no options are specified, the default is to throw an error if the target file exists or is a symbolic link.

Move a file

You can move a file by using the following method:

Files.move(Path source, Path target, CopyOption... options);
					

The available StandardCopyOptions enums available are:

If Files.move(...) is called with StandardCopyOption.COPY_ATTRIBUTES an UnsupportedOperationException is thrown.

Reading, Writing, and Creating Files

  1. Commonly used methods for small files

    If you have a small file and you would like to read its entire contents in one pass, you can use the readAllBytes(Path) or readAllLines(Path, Charset) method. These methods take care of most of the work for you, such as opening and closing the stream, but are not intended for handling large files. The following code shows how to use the readAllBytes method:

    Path file = ...;
    byte[] fileArray;
    fileArray = Files.readAllBytes(file);
    								

  2. Buffered I/O methods for text files

    The java.nio.file package supports channel I/O, which moves data in buffers, bypassing some of the layers that can bottleneck stream I/O.

    The newBufferedReader(Path, Charset) method opens a file for reading, returning a BufferedReader that can be used to read text from a file in an efficient manner.

    The following code snippet shows how to use the newBufferedReader method to read from a file. The file is encoded in "US-ASCII"

    Charset charset = Charset.forName("US-ASCII");
    try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
        String line = null;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    } catch (NoSuchFileException  x ) {
        System.err.format("No such file: %s", x.getFile());
    } catch (IOException  x) {
        System.err.println(x);
    }
    								

    You can use the newBufferedWriter(Path, Charset, OpenOption...) method to write to a file using a BufferedWriter:

    /**
     * Opens or creates a file for writing, returning a BufferedWriter that may be used to write text to the
     * file in an efficient manner. The options parameter specifies how the the file is created or opened.
     * If no options are present then this method works as if the CREATE, TRUNCATE_EXISTING, and WRITE options
     * are present. In other words, it opens the file for writing, creating the file if it doesn't exist, or
     * initially truncating an existing regular-file to a size of 0 if it exists.
     *
     * The Writer methods to write text throw IOException if the text cannot be encoded using the specified charset.
     */
    public static BufferedWriter newBufferedWriter(Path path,
                                                   Charset cs,
                                                   OpenOption... options) throws IOException
    								

    The following code snippet shows how to create a file encoded in "US-ASCII" using this method:

    Charset charset = Charset.forName("US-ASCII");
    String s = "ABC";
    try (BufferedWriter writer = Files.newBufferedWriter(file, charset)) {
        writer.write(s, 0, s.length());
    } catch (IOException x) {
        System.err.format("IOException: %s%n", x);
    }
    								

  3. Methods for unbuffered streams and interoperable with java.io APIs

    To open a file for reading, you can use the newInputStream(Path, OpenOption...) method. This method returns an unbuffered input stream for reading bytes from the file.

    try (InputStream in = Files.newInputStream(file);
        BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
        String line = null;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    } catch (NoSuchFileException  x) {
        System.err.println("No such file exists: " + x.getFile());
    } catch (IOException  x) {
        System.err.println(x);
    }
    								

Several of the Files methods take an optional OpenOptions parameter. This parameter is optional and the API tells you what the default behavior is for the method when none is specified. The following StandardOpenOptions enum constants are supported:

Glob argument

The newDirectoryStream method in the Files class accepts a glob argument:


/**
 * Opens a directory, returning a DirectoryStream to iterate over the entries in the directory.
 * The elements returned by the directory stream's iterator are of type Path, each one representing
 * an entry in the directory. The Path objects are obtained as if by resolving the name of the
 * directory entry against dir. The entries returned by the iterator are filtered by matching the
 * String representation of their file names against the given globbing pattern.
 */
public static DirectoryStream<Path> newDirectoryStream(Path dir, String glob) throws IOException;

					

You can use glob syntax to specify pattern-matching behavior. A glob pattern is specified as a string and is matched against other strings, such as directory or file names. For example:

Creating temporary files

You can create a temporary file using one of the following Files.createTempFile methods:


/**
 * Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate
 * its name. The resulting Path is associated with the same FileSystem as the given directory.
 *
 * The details as to how the name of the file is constructed is implementation dependent and therefore not specified.
 * Where possible the prefix and suffix are used to construct candidate names in the same manner as the
 * File.createTempFile(String,String,File) method.
 *
 * As with the File.createTempFile methods, this method is only part of a temporary-file facility. Where used as a work
 * files, the resulting file may be opened using the DELETE_ON_CLOSE option so that the file is deleted when the appropriate
 * close method is invoked. Alternatively, a shutdown-hook, or the File.deleteOnExit() mechanism may be used to delete the
 * file automatically.
 *
 * The attrs parameter is optional file-attributes to set atomically when creating the file. Each attribute is identified by
 * its name. If more than one attribute of the same name is included in the array then all but the last occurrence is ignored.
 * When no file attributes are specified, then the resulting file may have more restrictive access permissions to files
 * created by the File.createTempFile(String,String,File) method.
 */
 public static Path createTempFile(Path dir,
                  String prefix,
                  String suffix,
                  FileAttribute<?>... attrs)
                           throws IOException;

/**
 * Creates an empty file in the default temporary-file directory, using the given prefix and suffix to generate its name.
 * The resulting Path is associated with the default FileSystem.
 *
 * This method works in exactly the manner specified by the createTempFile(Path,String,String,FileAttribute[]) method for
 * the case that the dir parameter is the temporary-file directory.
 */
 public static Path createTempFile(String prefix,
                  String suffix,
                  FileAttribute<?>... attrs)
                           throws IOException;

					

The first method allows the code to specify a directory for the temporary file and the second method creates a new file in the default temporary-file directory. Both methods allow you to specify a suffix for the filename and the first method allows you to also specify a prefix. The following code snippet gives an example of the second method:

try {
    Path tempFile = Files.createTempFile(null, ".myapp");
    System.out.format("The temporary file: %s%n", tempFile);
} catch (IOException x) {
    System.err.format("IOException: %s%n", x);
}
					

The result of running this file would be something like the following:

The temporary file: C:\DOCUME~1\zaikin\LOCALS~1\Temp\2410322004839770958.myapp
					

Another example:

 try {
    Path tempFile = Files.createTempFile("mz", ".myapp");
     System.out.format("The temporary file: %s%n", tempFile);
} catch (IOException x) {
    System.err.format("IOException: %s%n", x);
}
					

produces:

The temporary file: C:\DOCUME~1\zaikin\LOCALS~1\Temp\mz7254193327871146359.myapp
					

A temporary file is just a simple file until YOU make sure that it is truly temporary, which means that an automatic mechanism must delete temporary files periodically or at a specified time. There are three approaches to automatic cleanup of temporary files:

Professional hosting         Free 'Oracle Certified Expert Web Services Developer 6' Guide     Free SCDJWS 5.0 Guide