Referencing Files and Directories
Before reading or writing any data, you must be able to refer to a file or directory on the filesystem. Java provides two main APIs: the legacy
Fileclass and the modern NIO.2Pathinterface introduced in Java 7. The OCP exam expects you to know both.
The Legacy File Class
java.io.File was the original way to represent a path. It still appears in older APIs and some exam questions.
javaFile f1 = new File("/home/user/data.txt"); // absolute
File f2 = new File("config/settings.properties"); // relative to working directory
File dir = new File("/home/user");
File child = new File(dir, "data.txt"); // parent + child constructorKey methods on File:
| Method | Description |
|---|---|
exists() |
Returns true if the path exists on disk |
isFile() |
true if it exists and is a regular file |
isDirectory() |
true if it exists and is a directory |
getName() |
Last element of the path |
getParent() |
Parent path as a String |
getAbsolutePath() |
Full path as a String |
toPath() |
Converts to a NIO.2 Path |
File has significant limitations: methods return boolean rather than throwing exceptions on failure, and it has poor support for symbolic links and file attributes.
The NIO.2 Path Interface
java.nio.file.Path is the modern replacement. A Path is an immutable object representing a path in the filesystem. It does not require the file to exist.
Creating a Path
java// Path.of() — preferred since Java 11
Path p1 = Path.of("/home/user/data.txt");
Path p2 = Path.of("/home", "user", "data.txt"); // variadic form
Path p3 = Path.of("config", "settings.properties");
// Paths.get() — older form, still valid on the exam
Path p4 = Paths.get("/home/user/data.txt");
Path p5 = Paths.get("/home", "user", "data.txt");Path.of() and Paths.get() are functionally equivalent. Prefer Path.of() in new code.
Absolute vs. Relative Paths
| Type | Description | Example (Unix) | Example (Windows) |
|---|---|---|---|
| Absolute | Starts from filesystem root | /home/user/file.txt |
C:\Users\user\file.txt |
| Relative | Resolved against the current working directory | docs/readme.txt |
docs\readme.txt |
javaPath abs = Path.of("/tmp/logs/app.log"); // absolute — starts with /
Path rel = Path.of("logs/app.log"); // relative — no leading /
System.out.println(abs.isAbsolute()); // true
System.out.println(rel.isAbsolute()); // falsePath Resolution
resolve() appends one path to another. If the argument is absolute, it replaces the base entirely.
javaPath base = Path.of("/home/user");
Path resolved = base.resolve("documents/notes.txt");
// → /home/user/documents/notes.txt
Path absolute = base.resolve(Path.of("/etc/passwd"));
// → /etc/passwd (absolute argument replaces base)Navigating Path Components
Path exposes individual components of the path string.
javaPath p = Path.of("/home/user/projects/demo/Main.java");
p.getFileName(); // Main.java
p.getParent(); // /home/user/projects/demo
p.getRoot(); // / (null for relative paths)
p.getNameCount(); // 5 (home, user, projects, demo, Main.java)
p.getName(0); // home
p.getName(4); // Main.java
p.subpath(1, 3); // user/projects (start inclusive, end exclusive)
getNameCount()does not count the root (/). Index 0 is the element immediately after the root.
Normalizing and Resolving Symbols
Paths can contain redundant elements like . (current directory) and .. (parent directory). normalize() collapses them.
javaPath messy = Path.of("/home/user/../user/./projects");
Path clean = messy.normalize();
// → /home/user/projectstoAbsolutePath() prepends the current working directory to a relative path without checking the filesystem.
javaPath rel = Path.of("data/file.txt");
Path abs = rel.toAbsolutePath();
// → /current/working/dir/data/file.txt (depends on JVM working dir)toRealPath() combines toAbsolutePath() + normalize() and follows symbolic links — but it requires the file to actually exist and may throw IOException.
Converting Between File and Path
java// File → Path
File file = new File("/tmp/data.txt");
Path path = file.toPath();
// Path → File
Path p = Path.of("/tmp/data.txt");
File f = p.toFile();Key Rules Summary
Fileis legacy; preferPath/ NIO.2 for new code.- Use
Path.of()orPaths.get()to createPathobjects — nonewkeyword. Pathis immutable; all transformation methods return new instances.getNameCount()counts elements after the root; index is 0-based.subpath(start, end)is start-inclusive, end-exclusive.normalize()removes.and..;toRealPath()also resolves symlinks and requires the file to exist.
References
- Oracle Docs — Path (java.nio.file)
- OCP Study Guide, Chapter 14 — I/O