File System in Java
Learn how Java works with files and directories using the modern NIO.2 API, including Path, Files, reading, writing, copying, moving, deleting, and directory operations.
Introduction to File I/O
File I/O means reading data from files and writing data to files stored on a computer's file system.
Modern Java applications commonly use the
java.nio.file package and its
Path and Files APIs.
import java.nio.file.Path;
import java.nio.file.Paths;
Path path =
Paths.get("data.txt");
Path
The Path interface represents a path in a file
system.
import java.nio.file.Path;
Path path = Path.of(
"data",
"students.txt"
);
System.out.println(path);
data/students.txt
Absolute and Relative Paths
A relative path is interpreted relative to the application's current working directory, while an absolute path identifies a location from the file system root.
Path relativePath =
Path.of("data.txt");
Path absolutePath =
relativePath.toAbsolutePath();
System.out.println(absolutePath);
Creating a Directory
Files.createDirectory() creates one directory
when its parent already exists.
import java.nio.file.Files;
import java.nio.file.Path;
Path directory =
Path.of("data");
Files.createDirectory(directory);
Files.createDirectories() when parent
directories may also need to be created.
Creating Nested Directories
Path directory =
Path.of("data", "students", "2026");
Files.createDirectories(directory);
Creating a File
Files.createFile() creates a new empty file.
Path file =
Path.of("data.txt");
Files.createFile(file);
createFile() normally
throws FileAlreadyExistsException.
Writing Text to a File
Files.writeString() provides a convenient way to
write text using the default character encoding behavior of
the API.
Path file =
Path.of("message.txt");
Files.writeString(
file,
"Welcome CIIT Institude 🤓❤️....!"
);
Reading Text from a File
String content =
Files.readString(file);
System.out.println(content);
Reading and Writing with UTF-8
When a specific character encoding is required, specify it explicitly.
import java.nio.charset.StandardCharsets;
Files.writeString(
file,
"Welcome CIIT Institude 🤓❤️....!",
StandardCharsets.UTF_8
);
String content =
Files.readString(
file,
StandardCharsets.UTF_8
);
Reading All Lines
List<String> lines =
Files.readAllLines(file);
for (String line : lines) {
System.out.println(line);
}
Reading Large Files with Files.lines()
For larger text files, Files.lines() provides a
lazy stream of lines and should be used with a
try-with-resources statement.
try (
Stream<String> lines =
Files.lines(file)
) {
lines.forEach(
System.out::println
);
}
Appending to a File
StandardOpenOption.APPEND can be used when new
content should be added instead of replacing existing content.
import java.nio.file.StandardOpenOption;
Files.writeString(
file,
System.lineSeparator()
+ "New line",
StandardOpenOption.APPEND
);
Checking Whether a File Exists
if (Files.exists(file)) {
System.out.println(
"File exists"
);
}
Checking File Type
if (Files.isRegularFile(file)) {
System.out.println(
"This is a regular file"
);
}
if (Files.isDirectory(file)) {
System.out.println(
"This is a directory"
);
}
Getting File Size
long size =
Files.size(file);
System.out.println(
"Size: " + size + " bytes"
);
Copying a File
Path copy =
Path.of("backup.txt");
Files.copy(
file,
copy
);
If the destination already exists, an option such as
REPLACE_EXISTING can be supplied when replacement
is intended.
Moving or Renaming a File
Path target =
Path.of("renamed.txt");
Files.move(
file,
target
);
Deleting a File
Files.delete() deletes the file or empty
directory represented by the path.
Files.delete(file);
Use Files.deleteIfExists() when the absence of the
target should not itself cause an exception.
Listing Directory Contents
Files.list() returns a stream of entries in a
directory.
Path directory =
Path.of("data");
try (
Stream<Path> entries =
Files.list(directory)
) {
entries.forEach(
System.out::println
);
}
Walking a Directory Tree
Files.walk() can recursively traverse a directory
tree.
Path root =
Path.of("data");
try (
Stream<Path> paths =
Files.walk(root)
) {
paths
.filter(Files::isRegularFile)
.forEach(
System.out::println
);
}
File Attributes
System.out.println(
Files.isReadable(file)
);
System.out.println(
Files.isWritable(file)
);
System.out.println(
Files.isExecutable(file)
);
BufferedReader
BufferedReader is useful for efficient
character-based reading, especially when processing text
incrementally.
try (
BufferedReader reader =
Files.newBufferedReader(file)
) {
String line;
while (
(line = reader.readLine())
!= null
) {
System.out.println(line);
}
}
BufferedWriter
try (
BufferedWriter writer =
Files.newBufferedWriter(file)
) {
writer.write("Hello Java");
writer.newLine();
writer.write(
"File I/O is useful"
);
}
Reading and Writing Bytes
The Files.readAllBytes() and
Files.write() methods can be used when working
with binary data or when the entire content can reasonably be
held in memory.
byte[] data =
Files.readAllBytes(file);
Path copy =
Path.of("copy.dat");
Files.write(
copy,
data
);
Handling File I/O Exceptions
Many NIO file operations throw checked
IOException.
try {
String content =
Files.readString(file);
System.out.println(content);
}
catch (IOException exception) {
System.out.println(
"File operation failed"
);
}
try-with-resources
Resources such as streams and readers should normally be managed with try-with-resources so they are closed automatically.
try (
Stream<String> lines =
Files.lines(file)
) {
lines.forEach(
System.out::println
);
}
catch (IOException exception) {
exception.printStackTrace();
}
Useful Path Operations
Path path =
Path.of(
"data",
"students.txt"
);
System.out.println(
path.getFileName()
);
System.out.println(
path.getParent()
);
System.out.println(
path.getNameCount()
);
normalize()
The normalize() method removes redundant
. and .. components from a path
where possible.
Path path =
Path.of(
"data",
"students",
"..",
"teachers"
);
Path normalized =
path.normalize();
System.out.println(normalized);
Example: Student File
Path file =
Path.of(
"students",
"student.txt"
);
try {
Files.createDirectories(
file.getParent()
);
Files.writeString(
file,
"Name: Samadhan"
);
String content =
Files.readString(file);
System.out.println(content);
}
catch (IOException exception) {
System.out.println(
"Unable to process file"
);
}
java.io vs java.nio.file
| Feature | java.io | java.nio.file |
|---|---|---|
| Path API | File | Path |
| Modern File Operations | Available but older style | Rich Files API |
| Directory Traversal | More manual | Files.list / Files.walk |
| Symbolic Links | Limited API | Strong support |
File I/O Best Practices
-
Prefer
PathandFilesfor modern Java file-system operations. - Use try-with-resources for streams, readers, and writers.
-
Handle
IOExceptionappropriately. - Specify character encoding explicitly when interoperability requires a particular encoding such as UTF-8.
- Avoid loading very large files entirely into memory.
- Validate file paths and permissions when paths originate from external input.
Interview Questions
File belongs to the older
java.io API, while
Path belongs to the modern NIO.2
file-system API.
AutoCloseable, helping prevent
resource leaks.
IOException or one of its more
specific subclasses.
Files.walk() for recursive directory
traversal.
Summary
Java provides powerful file-system APIs through
Path and Files. You can create,
read, write, copy, move, delete, and traverse files and
directories while using streams and try-with-resources
for safe resource management.