java.io vs java.nio
Fast recall
Quick revision
Core answer
java.io centers on streams, readers, and writers for straightforward sequential I/O. java.nio adds buffers, channels, charsets, selectors, memory mapping, and the NIO.2 Path/Files API. NIO is not automatically non-blocking; only APIs designed for it, such as selectable channels, provide that mode.Interview-ready guide
Interview answer
The classic java.io API is mainly stream-based. InputStream and OutputStream move bytes, while Reader and Writer move characters. This model is simple for sequential work such as reading a configuration file, writing a report, or processing one socket connection.
java.nio adds channels, buffers, selectors, and the modern Path and Files APIs. A channel can support reading, writing, or both, and data commonly moves through a ByteBuffer whose position, limit, and capacity control the operation. FileChannel also supports features such as random access and memory mapping.
For example, Files.readString(path, UTF_8) is the simplest choice for a small text file. FileChannel is useful when a program must jump to a particular file position. A server with many simultaneous connections may configure SocketChannel as non-blocking and use a Selector so one thread can watch many channels. NIO itself is not automatically non-blocking; a regular FileChannel is commonly blocking.
The two API families can work together. Files.newInputStream(path) returns a classic stream, while Channels.newInputStream(channel) adapts a channel. Neither package is always faster or better. Use the simplest API that meets the need, and choose NIO features when modern path handling, random access, explicit buffers, multiplexing, or asynchronous work provides a real benefit.
java.io vs java.nio
Direct Answer
java.io centers on streams, readers, and writers for straightforward sequential I/O. java.nio adds buffers, channels, charsets, selectors, memory mapping, and the NIO.2 Path/Files API. NIO is not automatically non-blocking; only APIs designed for it, such as selectable channels, provide that mode.
Deep Dive & Architecture
“NIO means non-blocking I/O” is a memorable but false expansion. NIO introduced buffers and channels, and only selectable channels can participate in selector-driven non-blocking readiness. FileChannel is not selectable. Asynchronous channels use a different completion model with Future or CompletionHandler.
A ByteBuffer has position, limit, and capacity. Channel reads advance the position as bytes arrive; flip() changes the buffer from filling mode to draining mode by making the former position the new limit and resetting position to zero. Forgetting that state transition is a common source of empty or stale reads.
Selectors can reduce the need for one blocked platform thread per connection, but they add state-machine complexity. Simple blocking I/O—especially with modern lightweight-thread strategies—can still be the clearer architecture.
Code Example
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
class IoVsNio {
public static void main(String[] args) throws Exception {
Path file = Files.writeString(
Files.createTempFile("nio-demo-", ".txt"), "channel");
try (FileChannel channel = FileChannel.open(file, StandardOpenOption.READ)) {
ByteBuffer buffer = ByteBuffer.allocate(16);
channel.read(buffer);
buffer.flip();
System.out.println(StandardCharsets.UTF_8.decode(buffer));
} finally {
Files.deleteIfExists(file);
}
}
}
Check your understanding
Answer these without looking back at the article.
- Is FileChannel non-blocking?
- What does ByteBuffer.flip do?
- When is a Selector useful?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.