Skip to content

File Object

In computer systems, files are a crucial method of storage. Java's standard library, java.io, provides the File object for handling files and directories.

To construct a File object, you need to provide the file path:

java
import java.io.*;

public class Main {
    public static void main(String[] args) {
        File f = new File("C:\\Windows\\notepad.exe");
        System.out.println(f);
    }
}

When constructing a File object, you can pass either an absolute path or a relative path. An absolute path starts with the root directory and is a complete path, for example:

java
File f = new File("C:\\Windows\\notepad.exe");

Note that on Windows platforms, the backslash \ is used as the path separator, and in Java strings, you need to use \\ to represent a single backslash. On Linux platforms, the forward slash / is used as the path separator:

java
File f = new File("/usr/bin/javac");

When passing a relative path, adding the current directory in front of it forms an absolute path:

java
// Assuming the current directory is C:\Docs
File f1 = new File("sub\\javac"); // Absolute path is C:\Docs\sub\javac
File f2 = new File(".\\sub\\javac"); // Absolute path is C:\Docs\sub\javac
File f3 = new File("..\\sub\\javac"); // Absolute path is C:\sub\javac

You can use . to represent the current directory and .. to represent the parent directory.

The File object can represent paths in three forms: one is getPath(), which returns the path passed to the constructor; another is getAbsolutePath(), which returns the absolute path; and the third is getCanonicalPath(), which is similar to the absolute path but returns the canonical path.

What is a canonical path? Let's look at the following code:

java
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        File f = new File("..");
        System.out.println(f.getPath());
        System.out.println(f.getAbsolutePath());
        System.out.println(f.getCanonicalPath());
    }
}

An absolute path can be represented as C:\Windows\System32\..\notepad.exe, while the canonical path converts . and .. into the standard absolute path: C:\Windows\notepad.exe.

Since Windows and Linux have different path separators, the File object has a static variable to represent the system separator for the current platform:

java
System.out.println(File.separator); // Prints "\" or "/" depending on the current platform

Files and Directories

A File object can represent both files and directories. It is important to note that constructing a File object does not result in any disk operations, even if the specified file or directory does not exist. Only when we call certain methods on the File object does the actual disk operation occur.

For example, calling isFile() checks if the File object represents an existing file, while calling isDirectory() checks if it represents an existing directory:

java
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        File f1 = new File("C:\\Windows");
        File f2 = new File("C:\\Windows\\notepad.exe");
        File f3 = new File("C:\\Windows\\nothing");
        System.out.println(f1.isFile());
        System.out.println(f1.isDirectory());
        System.out.println(f2.isFile());
        System.out.println(f2.isDirectory());
        System.out.println(f3.isFile());
        System.out.println(f3.isDirectory());
    }
}

When obtaining a file through the File object, you can further check its permissions and size:

  • boolean canRead(): Check if it is readable.
  • boolean canWrite(): Check if it is writable.
  • boolean canExecute(): Check if it is executable.
  • long length(): Get the file size in bytes.

For directories, whether it is executable indicates if you can list its contained files and subdirectories.

Creating and Deleting Files

When the File object represents a file, you can create a new file using createNewFile() and delete that file using delete():

java
File file = new File("/path/to/file");
if (file.createNewFile()) {
    // File created successfully:
    // TODO:
    if (file.delete()) {
        // File deleted successfully:
    }
}

Sometimes, a program needs to read and write temporary files. The File object provides createTempFile() to create a temporary file and deleteOnExit() to automatically delete that file when the JVM exits.

java
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        File f = File.createTempFile("tmp-", ".txt"); // Provide prefix and suffix for the temp file
        f.deleteOnExit(); // Automatically delete when JVM exits
        System.out.println(f.isFile());
        System.out.println(f.getAbsolutePath());
    }
}

Traversing Files and Directories

When the File object represents a directory, you can use list() and listFiles() to list the files and subdirectory names under that directory. listFiles() provides a series of overloaded methods to filter unwanted files and directories:

java
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        File f = new File("C:\\Windows");
        File[] fs1 = f.listFiles(); // List all files and subdirectories
        printFiles(fs1);
        File[] fs2 = f.listFiles(new FilenameFilter() { // Only list .exe files
            public boolean accept(File dir, String name) {
                return name.endsWith(".exe"); // Return true to accept this file
            }
        });
        printFiles(fs2);
    }

    static void printFiles(File[] files) {
        System.out.println("==========");
        if (files != null) {
            for (File f : files) {
                System.out.println(f);
            }
        }
        System.out.println("==========");
    }
}

Similar to file operations, if the File object represents a directory, you can create and delete directories using the following methods:

  • boolean mkdir(): Create the directory represented by the current File object.
  • boolean mkdirs(): Create the directory represented by the current File object, and create any nonexistent parent directories as necessary.
  • boolean delete(): Delete the directory represented by the current File object; the directory must be empty to be deleted successfully.

Path

The Java standard library also provides a Path object located in the java.nio.file package. The Path object is similar to the File object but offers simpler operations:

java
import java.io.*;
import java.nio.file.*;

public class Main {
    public static void main(String[] args) throws IOException {
        Path p1 = Paths.get(".", "project", "study"); // Construct a Path object
        System.out.println(p1);
        Path p2 = p1.toAbsolutePath(); // Convert to absolute path
        System.out.println(p2);
        Path p3 = p2.normalize(); // Convert to canonical path
        System.out.println(p3);
        File f = p3.toFile(); // Convert to File object
        System.out.println(f);
        for (Path p : Paths.get("..").toAbsolutePath()) { // Directly iterate through Path
            System.out.println("  " + p);
        }
    }
}

If you need to perform complex operations such as concatenating or traversing directories, using the Path object is more convenient.

Exercise

Please use the File object to list all subdirectories and files in a specified directory, and print them in a hierarchical format.

For example, the output could be:

Documents/
  word/
    1.docx
    2.docx
    work/
      abc.doc
  ppt/
  other/

If no parameters are specified, use the current directory; if parameters are provided, use the specified directory.

Summary

The java.io.File object in the Java standard library represents a file or directory:

  • Creating a File object does not involve IO operations.
  • You can obtain paths/absolute paths/canonical paths using: getPath(), getAbsolutePath(), and getCanonicalPath().
  • You can list files and subdirectories in a directory using: list() and listFiles().
  • You can create or delete files and directories.
File Object has loaded