Topic 106 of 119 14. Additional Java Topics Interactive Tutorial

Java File I/O: java.nio.file.Path, Files, Streams, and Modern File Handling

9 mins read Last updated: 22 Aug 2026 15,338 views

Direct Answer & Core Concept

Java File I/O allows applications to create, read, write, copy, move, delete, and manage files and directories. Modern Java provides the NIO.2 API through the java.nio.file package, which offers a cleaner and more flexible approach than many of the older java.io.File APIs.

The two most important classes for modern file handling are Path and Files. Path represents the location of a file or directory, while Files provides static methods for performing operations on those paths.

Java also provides file streams such as Files.lines(), Files.list(), and Files.walk() for processing potentially large amounts of file-system data efficiently.

Detailed Explanation & Mechanics

What Is Java File I/O?

File I/O stands for File Input/Output. It refers to reading data from and writing data to files stored on a file system.

Typical file operations include:

  • Creating files

  • Reading files

  • Writing files

  • Appending data

  • Copying files

  • Moving files

  • Deleting files

  • Creating directories

  • Listing directory contents

  • Walking through directory trees

  • Checking file properties

Modern Java applications commonly use:

Main.java
Run Online
import java.nio.file.Path;
import java.nio.file.Files;

Java File I/O Packages

Java provides two major APIs for file handling.

Traditional I/O

This includes classes such as:

Main.java
Run Online
FileFileInputStreamFileOutputStreamFileReaderFileWriterBufferedReaderBufferedWriter

Modern NIO.2

Important classes include:

Main.java
Run Online
PathPathsFilesFileSystemFileSystems

For modern application development, Path and Files are often the preferred starting point.


What Is Path in Java?

Path represents a file-system path.

For example:

Main.java
Run Online
Path path = Path.of("data.txt");

The Path object represents the location:

It does not mean that the file necessarily exists.

This distinction is important:

A Path represents a location; it does not guarantee that a file or directory exists at that location.


Creating a Path

Modern Java allows:

Main.java
Run Online
Path path = Path.of("data.txt");

You can also create paths containing directories:

Main.java
Run Online
Path path = Path.of("documents", "notes", "data.txt");

The resulting path is constructed using the platform's file-system conventions.


Absolute and Relative Paths

A relative path is interpreted relative to the application's current working directory.

Main.java
Run Online
Path path = Path.of("data.txt");

An absolute path identifies a location from the root of the file system.

For example, on Linux:

Main.java
Run Online
Path path = Path.of("/home/user/data.txt");

On Windows:

Main.java
Run Online
Path path = Path.of("C:\\Users\\User\\data.txt");

Prefer constructing paths with Path rather than manually joining strings.


Converting a Path to an Absolute Path

You can use:

Main.java
Run Online
Path path = Path.of("data.txt");
Path absolute = path.toAbsolutePath();
System.out.println(absolute);

This converts the path to an absolute representation.

It does not necessarily mean the file exists.


Path Methods

Path provides many useful methods.

Main.java
Run Online
Path path = Path.of("documents", "java", "notes.txt");

You can inspect different parts:

Main.java
Run Online
System.out.println(path.getFileName());
System.out.println(path.getParent());
System.out.println(path.getRoot());

Other useful methods include:

Main.java
Run Online
path.isAbsolute();
path.toAbsolutePath();
path.normalize();
path.resolve(...);
path.relativize(...);

resolve() in Java

resolve() is useful for constructing child paths.

Instead of:

Main.java
Run Online
String path = "documents/" + "notes.txt";

use:

Main.java
Run Online
Path directory = Path.of("documents");
Path file = directory.resolve("notes.txt");
System.out.println(file);

This is more portable because the path implementation handles the appropriate separator.


normalize()

A path may contain redundant components such as:

Main.java
Run Online
documents/../data/file.txt

You can normalize it:

Main.java
Run Online
Path path = Path.of( "documents", "..", "data", "file.txt");
Path normalized = path.normalize();
System.out.println(normalized);

normalize() removes redundant . and .. elements where possible.

It does not necessarily verify that the resulting path exists.


relativize()

relativize() calculates a path from one location to another.

Main.java
Run Online
Path base = Path.of("/home/user");
Path target = Path.of("/home/user/documents/file.txt");
Path relative = base.relativize(target);
System.out.println(relative);

The result represents the relative path from base to target.

Both paths generally need to be compatible, such as both being absolute or both being relative.


What Is the Files Class?

Files is a utility class containing static methods for working with files and directories.

For example:

Main.java
Run Online
Path path = Path.of("data.txt");
Files.exists(path);

You can use Files for operations such as:

Main.java
Run Online
createreadwritecopymovedeletechecklistwalk

Checking Whether a File Exists

Main.java
Run Online
Path path = Path.of("data.txt");
if (Files.exists(path)) {
    System.out.println("File exists");
}

You can also check for a directory:

Main.java
Run Online
Path directory = Path.of("documents");
if (Files.isDirectory(directory)) {
    System.out.println("It is a directory");
}

And a regular file:

Main.java
Run Online
if (Files.isRegularFile(path)) {
    System.out.println("It is a regular file");
}

Creating a File

Use:

Main.java
Run Online
Path path = Path.of("data.txt");
Files.createFile(path);

If the file already exists, the operation normally fails with an exception.

A common pattern is:

Main.java
Run Online
if (Files.notExists(path)) {
    Files.createFile(path);
}

However, for concurrent programs, checking and then creating is not an atomic operation. Often it is better to perform the operation and handle the resulting exception according to the application's requirements.


Creating Directories

Create one directory:

Main.java
Run Online
Path directory = Path.of("documents");
Files.createDirectory(directory);

For multiple missing parent directories:

Main.java
Run Online
Path directory = Path.of("documents", "java", "examples");
Files.createDirectories(directory);

createDirectories() creates missing parent directories as necessary.


Writing Text to a File

For small text files, Files.writeString() is convenient.

Main.java
Run Online
Path path = Path.of("message.txt");
Files.writeString(path, "Hello Java!");

This is one of the simplest modern ways to write text.


Reading Text From a File

Use:

Main.java
Run Online
Path path = Path.of("message.txt");
String content = Files.readString(path);
System.out.println(content);

This is convenient for small files because the entire content is loaded into memory.

For very large files, a streaming approach may be more appropriate.


Writing Multiple Lines

You can write a collection of strings:

Main.java
Run Online
Path path = Path.of("names.txt");
List<String> names = List.of( "Alice", "Bob", "Charlie");
Files.write(path, names);

You need:

Each element is written as a line using the method's default text encoding behavior unless another charset is specified.


Reading All Lines

You can read all lines into a list:

Main.java
Run Online
Path path = Path.of("names.txt");
List<String> lines = Files.readAllLines(path);
for (String line : lines) {
    System.out.println(line);
}

This is convenient for reasonably sized text files.

For very large files, loading every line into a list may consume significant memory.


Specifying a Charset

It is often a good idea to be explicit about the character encoding when the format requires it.

For example:

Main.java
Run Online
import java.nio.charset.StandardCharsets;
Path path = Path.of("message.txt");
String content = Files.readString(path, StandardCharsets.UTF_8);

Similarly:

Main.java
Run Online
Files.writeString( path, "Hello Java", StandardCharsets.UTF_8);

UTF-8 is a common choice for modern applications.


Reading a File With Files.lines()

Files.lines() returns a lazy Stream<String> of lines.

Main.java
Run Online
Path path = Path.of("names.txt");
try(Stream<String> lines = Files.lines(path)) {
    lines.forEach(System.out::println);
}

The stream should be closed after use, which is why try-with-resources is appropriate.


Filtering File Lines With Streams

You can combine Files.lines() with the Stream API.

Main.java
Run Online
try(Stream<String> lines = Files.lines(Path.of("users.txt"))) {
    lines.filter(line -> line.contains("admin")) .forEach(System.out::println);
}

This allows large files to be processed incrementally rather than automatically loading all lines into a list.


Counting Lines

Main.java
Run Online
try(Stream<String> lines = Files.lines(Path.of("data.txt"))) {
    long count = lines.count();
    System.out.println("Lines: " + count);
}

The stream processes the file as needed.


Finding Matching Lines

Main.java
Run Online
try(Stream<String> lines = Files.lines(Path.of("users.txt"))) {
    lines.filter(line -> line.startsWith("admin")) .forEach(System.out::println);
}

This is useful for log processing, configuration files, reports, and other line-oriented text.


Appending to a File

By default, writing can replace the existing file contents.

To append instead:

Main.java
Run Online
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;
Path path = Path.of("log.txt");
Files.writeString( path, "New log entry\n", CREATE, APPEND);

Here:

Main.java
Run Online
CREATE -> create the file if neededAPPEND -> write at the end

StandardOpenOption

Java provides predefined options for file operations.

Common options include:

Main.java
Run Online
CREATECREATE_NEWAPPENDTRUNCATE_EXISTINGREADWRITE

For example:

Main.java
Run Online
Files.writeString( path, "Hello", StandardOpenOption.CREATE, StandardOpenOption.APPEND);

Using explicit options can make the intended file behavior clearer.


Copying a File

Use:

Main.java
Run Online
Path source = Path.of("source.txt");
Path target = Path.of("backup.txt");
Files.copy(source, target);

If the destination already exists, the operation normally fails.

To replace it:

Main.java
Run Online
Files.copy( source, target, StandardCopyOption.REPLACE_EXISTING);

Copying With File Attributes

Depending on the file system and operation, you can also request attribute copying:

Main.java
Run Online
Files.copy( source, target, StandardCopyOption.COPY_ATTRIBUTES);

The exact attributes that can be copied depend on the file system provider.


Moving a File

Use:

Main.java
Run Online
Path source = Path.of("old.txt");
Path target = Path.of("new.txt");
Files.move(source, target);

You can combine it with:

Main.java
Run Online
StandardCopyOption.REPLACE_EXISTING

when replacement behavior is required.


Renaming a File

A rename is commonly performed with Files.move():

Main.java
Run Online
Path oldPath = Path.of("old-name.txt");
Path newPath = Path.of("new-name.txt");
Files.move(oldPath, newPath);

This is preferable to treating renaming as a completely separate file-system operation.


Deleting a File

Use:

Main.java
Run Online
Path path = Path.of("data.txt");
Files.delete(path);

If you want deletion only when the target exists:

Main.java
Run Online
Files.deleteIfExists(path);

deleteIfExists() is useful when absence should not itself be considered an error.


Listing Directory Contents

Files.list() returns a stream containing the entries directly inside a directory.

Main.java
Run Online
Path directory = Path.of("documents");
try(Stream<Path> paths = Files.list(directory)) {
    paths.forEach(System.out::println);
}

This lists direct children rather than recursively walking the entire directory tree.


Filtering Directory Contents

You can use Stream operations:

Main.java
Run Online
try(Stream<Path> paths = Files.list(Path.of("documents"))) {
    paths.filter(Files::isRegularFile) .forEach(System.out::println);
}

This displays only regular files.


Walking a Directory Tree

For recursive traversal, use:

Example:

Main.java
Run Online
try(Stream<Path> paths = Files.walk(Path.of("documents"))) {
    paths.filter(Files::isRegularFile) .forEach(System.out::println);
}

This can traverse nested directories.

Because the returned stream may hold resources, use try-with-resources.


Files.list() vs Files.walk()

The difference is important.

Files.list()

Processes direct children:

Architecture Diagram
documents/
├── a.txt
├── b.txt
└── sub/

It returns:

Files.walk()

Can recursively process:

Architecture Diagram
documents/
├── a.txt
├── b.txt
└── sub/
    ├── c.txt
    └── d.txt

It can return paths from nested directories as well.


Finding Files With Files.find()

Files.find() can search a directory tree using a predicate.

Example:

Main.java
Run Online
try(Stream<Path> paths = Files.find( Path.of("documents"), 10,(path, attributes) -> attributes.isRegularFile() && path.toString().endsWith(".java"))) {
    paths.forEach(System.out::println);
}

The 10 represents the maximum traversal depth.


File Attributes

Java provides methods for checking file metadata.

For example:

Main.java
Run Online
Path path = Path.of("data.txt");
System.out.println( Files.size(path));

You can also check:

Main.java
Run Online
Files.isReadable(path);
Files.isWritable(path);
Files.isExecutable(path);

These checks can be useful, but they should not be treated as a guarantee that a later operation will succeed. File-system state and permissions can change between operations.


Last Modified Time

You can read the last modified timestamp:

Main.java
Run Online
Path path = Path.of("data.txt");
var time = Files.getLastModifiedTime(path);
System.out.println(time);

You can also update it:

Main.java
Run Online
Files.setLastModifiedTime(path, time);

Basic File Attributes

For more detailed information:

Main.java
Run Online
var attributes = Files.readAttributes( path, java.nio.file.attribute.BasicFileAttributes.class);
System.out.println(attributes.size());
System.out.println(attributes.creationTime());
System.out.println(attributes.lastModifiedTime());
System.out.println(attributes.isRegularFile());
System.out.println(attributes.isDirectory());

This provides several file-system attributes in one operation.


Symbolic Links

Modern file systems can contain symbolic links.

You can check whether a path itself is a symbolic link:

Main.java
Run Online
if (Files.isSymbolicLink(path)) {
    System.out.println("Symbolic link");
}

Many Files operations follow symbolic links by default where appropriate, but APIs often provide options to control link handling.

For security-sensitive code, understand symbolic-link behavior carefully before performing operations recursively.


LinkOption.NOFOLLOW_LINKS

For operations where you do not want to follow symbolic links, Java provides:

Main.java
Run Online
LinkOption.NOFOLLOW_LINKS

For example:

Main.java
Run Online
boolean exists = Files.exists( path, LinkOption.NOFOLLOW_LINKS);

This checks the path itself rather than following a symbolic link.


File I/O Exceptions

File operations can fail for many reasons:

  • File does not exist

  • Permission denied

  • Invalid path

  • File already exists

  • Directory is not accessible

  • Storage errors

  • Network file-system problems

Many NIO file operations throw IOException.

Example:

Main.java
Run Online
try {
    String content = Files.readString(Path.of("data.txt"));
    System.out.println(content);
} catch (IOException e) {
    System.out.println( "Unable to read file: " + e.getMessage());
}

Try-With-Resources

File streams should generally be closed after use.

Java's try-with-resources makes this easier:

Main.java
Run Online
try(Stream<String> lines = Files.lines(Path.of("data.txt"))) {
    lines.forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}

The resource is automatically closed when the try block finishes.


Buffered File Processing

For line-oriented processing, Files.newBufferedReader() can be useful.

Main.java
Run Online
Path path = Path.of("data.txt");
try(BufferedReader reader = Files.newBufferedReader(path)) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

This is useful when you need explicit control over sequential reading.


Buffered Writing

You can create a buffered writer:

Main.java
Run Online
Path path = Path.of("output.txt");
try(BufferedWriter writer = Files.newBufferedWriter(path)) {
    writer.write("Hello Java");
    writer.newLine();
    writer.write("File I/O");
}

This is useful for applications that write text progressively.


Byte-Based File I/O

Not every file is text.

Images, PDFs, ZIP files, and many other formats contain binary data.

For small binary files:

Main.java
Run Online
Path source = Path.of("image.jpg");
byte[] data = Files.readAllBytes(source);

You can write bytes:

Main.java
Run Online
Path target = Path.of("copy.jpg");
Files.write(target, data);

For large binary files, streaming or channel-based approaches are generally preferable.


File InputStream and OutputStream

NIO.2 also works with traditional stream concepts.

You can open a stream through Files:

Main.java
Run Online
try(InputStream input = Files.newInputStream(Path.of("data.bin"))) {
    int value;
    while ((value = input.read()) != -1) {
        // Process byte
    }
}

For output:

Main.java
Run Online
try(OutputStream output = Files.newOutputStream(Path.of("data.bin"))) {
    output.write(65);
}

File Channels

For advanced file operations, Java provides FileChannel.

Main.java
Run Online
try(FileChannel channel = FileChannel.open( Path.of("data.bin"), StandardOpenOption.READ)) {
    // Channel operations
}

Channels support operations such as:

  • Random access

  • Position-based reads and writes

  • File locking

  • Efficient transfer operations

  • Memory mapping


When Should You Use Files.readString()?

Use Files.readString() when:

  • The file is reasonably small.

  • You need the entire text at once.

  • Simplicity is important.

Example:

Main.java
Run Online
String config = Files.readString(Path.of("config.txt"));

Avoid loading extremely large files into one String unnecessarily.


When Should You Use Files.lines()?

Use Files.lines() when:

  • The file is line-oriented.

  • You want to process lines one at a time.

  • You want to use Stream operations.

  • The file may be larger than you want to load completely into memory.

Example:

Main.java
Run Online
try(Stream<String> lines = Files.lines(Path.of("server.log"))) {
    lines.filter(line -> line.contains("ERROR")) .forEach(System.out::println);
}

Complete File Copy Example

Main.java
Run Online
import java.io.IOException;
import java.nio.file.*;
public class FileCopyExample {
    public static void main(String[] args) {
        Path source = Path.of("source.txt");
        Path target = Path.of("backup.txt");
        try {
            Files.copy( source, target, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("File copied successfully.");
        } catch (IOException e) {
            System.out.println( "Copy failed: " + e.getMessage());
        }
    }
}

This example demonstrates the modern Path and Files APIs.


Complete File Processing Example

Main.java
Run Online
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Files;
import java.util.stream.Stream;
public class FileProcessor {
    public static void main(String[] args) {
        Path path = Path.of("application.log");
        try(Stream<String> lines = Files.lines(path)) {
            long errors = lines .filter(line -> line.contains("ERROR")) .count();
            System.out.println( "Error count: " + errors);
        } catch (IOException e) {
            System.out.println( "Unable to process file: " + e.getMessage());
        }
    }
}

This is a practical example of combining NIO.2 with the Stream API.


Modern File Handling vs java.io.File

The older API:

Main.java
Run Online
File file = new File("data.txt");

still exists and is useful in legacy code.

Modern NIO.2:

Main.java
Run Online
Path path = Path.of("data.txt");

generally provides a richer API for modern file-system operations.

For example:

Main.java
Run Online
Files.copy(source, target);
Files.move(source, target);
Files.walk(path);
Files.readString(path);

This makes many common operations concise.


Path vs File

FeatureFilePath
APILegacy I/ONIO.2
Packagejava.iojava.nio.file
Path operationsLimitedRich
File operationsInstance methodsFiles utility API
Directory traversalLimitedFiles.walk() / find()
Symbolic linksLimitedBetter support
Modern file-system APINoYes

File has not been removed, so existing applications can continue to use it.


Converting Between File and Path

Legacy code can be integrated with NIO.2.

Convert File to Path:

Main.java
Run Online
File file = new File("data.txt");
Path path = file.toPath();

Convert Path to File:

Main.java
Run Online
Path path = Path.of("data.txt");
File file = path.toFile();

This is useful when modernizing older applications gradually.


Common Java File I/O Mistakes

Mistake 1: Building Paths With String Concatenation

Avoid:

Main.java
Run Online
String path = "documents/" + fileName;

Prefer:

Main.java
Run Online
Path path = Path.of("documents").resolve(fileName);

Mistake 2: Loading Huge Files Into Memory

This can be problematic:

Main.java
Run Online
String content = Files.readString(path);

when path points to a very large file.

Consider:

or buffered/chunked processing.


Mistake 3: Forgetting to Close Streams

Avoid leaving:

Main.java
Run Online
Stream<String> lines = Files.lines(path);

open.

Prefer:

Main.java
Run Online
try(Stream<String> lines = Files.lines(path)) {
    // Process
}

Mistake 4: Assuming Path Means the File Exists

This:

Main.java
Run Online
Path path = Path.of("data.txt");

only creates a path representation.

Check the file system separately:

when necessary.


Mistake 5: Ignoring Character Encoding

For portable text processing, explicitly specify the charset when the encoding is part of the file format contract.

Main.java
Run Online
Files.readString( path, StandardCharsets.UTF_8);

Java File I/O Best Practices

Use Path and Files

For new applications, prefer the NIO.2 API for most file-system operations.

Use Try-With-Resources

Always close streams, readers, writers, and other closeable resources.

Use Streams for Large Line-Oriented Files

Avoid loading an unnecessarily large file entirely into memory.

Specify Encoding When Appropriate

UTF-8 is a common choice for text files.

Handle IOException

File systems are external resources and operations can fail.

Use resolve()

Build paths using Path instead of manually joining strings.

Be Careful With Recursive Operations

Operations such as Files.walk() can process large directory trees.

Consider Symbolic Links

Security-sensitive file operations should understand whether symbolic links are followed.


Java File I/O Quick Reference

Main.java
Run Online
// Create Path
Path path = Path.of("data.txt");
// Check existence
Files.exists(path);
// Create file
Files.createFile(path);
// Create directories
Files.createDirectories(Path.of("documents/java"));
// Read text
String text = Files.readString(path);
// Write text
Files.writeString(path, "Hello");
// Read all lines
List<String> lines = Files.readAllLines(path);
// Stream lines
Files.lines(path);
// Copy
Files.copy(source, target);
// Move
Files.move(source, target);
// Delete
Files.delete(path);
// Delete if present
Files.deleteIfExists(path);
// List directory
Files.list(directory);
// Walk directory tree
Files.walk(directory);
// File size
Files.size(path);

Frequently Asked Questions

What is Path in Java?

Path is an interface from java.nio.file that represents a path to a file or directory.

What is the Files class in Java?

Files is a utility class containing static methods for creating, reading, writing, copying, moving, deleting, and inspecting files and directories.

Is Path better than File?

For modern Java development, Path and the NIO.2 API generally provide a richer and more flexible file-system API. File remains available for legacy compatibility.

How do I read a text file in Java?

For a small text file:

Main.java
Run Online
String text = Files.readString(Path.of("data.txt"));

For line-oriented processing:

Main.java
Run Online
try(Stream<String> lines = Files.lines(Path.of("data.txt"))) {
    lines.forEach(System.out::println);
}

How do I write a file in Java?

Use:

Main.java
Run Online
Files.writeString( Path.of("data.txt"), "Hello Java");

How do I append text to a file?

Use StandardOpenOption.APPEND:

Main.java
Run Online
Files.writeString( path, "New line\n", StandardOpenOption.CREATE, StandardOpenOption.APPEND);

How do I copy a file in Java?

Use:

Main.java
Run Online
Files.copy(source, target);

Use REPLACE_EXISTING when replacing an existing destination is intended.

How do I delete a file?

Use:

or:

Main.java
Run Online
Files.deleteIfExists(path);

What is the difference between Files.list() and Files.walk()?

Files.list() processes the direct entries of a directory. Files.walk() can recursively traverse a directory tree to a specified depth.

Why should Files.lines() be used inside try-with-resources?

The returned stream is associated with an open file resource. Closing the stream releases that resource.

Does Path.of() create a file?

No. Path.of() creates a Path object representing a location. It does not create the actual file.

What exception is commonly used for Java file operations?

Many NIO.2 operations throw IOException. More specific subclasses such as NoSuchFileException, AccessDeniedException, and FileAlreadyExistsException may provide additional information about particular failures.

Graphics and Design Ideas

Graphic 1: Modern Java File I/O Architecture

Main.java
Run Online
Java File I/O | java.nio.file | +--------+--------+ | | Path Files | | File/Directory Operations | +---------+-------+---------+ | | | | Read Write Copy Move | | | | Streams Streams Files Files

Graphic 2: Path vs Files

Main.java
Run Online
Path | +-- Represents location +-- resolve() +-- normalize() +-- getFileName() +-- getParent()Files | +-- read +-- write +-- copy +-- move +-- delete +-- list +-- walk

Graphic 3: File Reading Choices

Main.java
Run Online
Read File | +-----------+-----------+ | | | Small Text Line-Based Binary | | | readString() lines() readAllBytes() | Stream<String>

Graphic 4: Directory Traversal

Architecture Diagram
documents/
│
├── java.txt
├── notes.txt
│
└── projects/
    ├── app.java
    └── test.java

Show:

Main.java
Run Online
Files.list()↓Direct children onlyFiles.walk()↓Recursive traversal

Graphic 5: File Operation Lifecycle

Main.java
Run Online
Path | v Check | v +----+----+ | | Exists Missing | | v v Read/Write Create | | +----+----+ | v Process | v Close Resources

These diagrams can be placed throughout the article to visually explain the relationship between Path, Files, streams, and the Java file system API.

Runnable Code Example: Java File I/O

Java 17+
Main.java
Run Online
import java.nio.file.Files;
import java.nio.file.Path;
import java.io.IOException;
public class ModernFileIoDemo {
    public static void main(String[] args) throws IOException {
        Path tempFile = Files.createTempFile("demo", ".txt");
        Files.writeString(tempFile, "Hello Java NIO.2 Files!");
        String content = Files.readString(tempFile);
        System.out.println("File Read Content: " + content);
        Files.deleteIfExists(tempFile);
        System.out.println("Cleaned up temp file.");
    }
}

Common Java Technical Interview Questions & Answers

Interview Prep
Q1

Why is java.nio.file.Files preferred over legacy java.io.File?

Files provides modern exception handling, better performance, atomic operations, metadata support, and seamless Stream API integration.
Q2

How does Files.lines() handle large files efficiently?

It lazily streams lines from the underlying disk buffer without loading the entire multi-gigabyte file into memory.

Key Takeaways, Best Practices & Clean Code Rules

Java Best Practice & Production Rules

Use Files.readString() and Files.writeString() for small files, and Files.lines() with try-with-resources for large datasets.