Fundamentals 12 min read

Master Java I/O: Streams, NIO, and Serialization Explained

This article introduces Java I/O streams, explains how to efficiently read large files using buffered streams and NIO, details the core components of Java NIO (Channel, Buffer, Selector), and covers object serialization, the role of serialVersionUID, and alternative serialization frameworks.

Java Interview Crash Guide
Java Interview Crash Guide
Java Interview Crash Guide
Master Java I/O: Streams, NIO, and Serialization Explained

1. Introduction to Java I/O Streams

IO (Input Output) is used for data input and output. Java abstracts various sources (keyboard, file, network) as streams, which are ordered data from source to destination, allowing uniform access.

Based on data direction, streams are input (read‑only) or output (write‑only).

Based on data type, streams are byte streams (8‑bit) or character streams (16‑bit).

Based on functionality, streams are node (low‑level) streams that directly read/write devices, or processing (high‑level) streams that wrap node streams to simplify or improve efficiency.

Java provides many classes for I/O; abstract base classes are shown in black, node streams in red, processing streams in blue.

Naming conventions indicate purpose:

File* streams access files.

ByteArray*/CharArray* streams access memory arrays.

Piped* streams implement pipes for inter‑process communication.

String* streams work with strings in memory.

Buffered* streams add buffering to reduce I/O operations.

InputStreamReader / OutputStreamWriter are conversion streams between byte and character streams.

Object* streams handle object serialization.

Print* streams simplify printing.

Pushback* streams allow unread data to be pushed back into the buffer.

Data* streams read/write Java primitive types.

2. How to Open a Large File with Streams

To avoid loading an entire file into memory, read it in chunks.

Use buffered streams, which maintain an internal buffer to reduce device interactions. Reads fill the buffer; subsequent reads come from the buffer until it empties.

Use NIO with memory‑mapped files, allowing the file (or a region) to be mapped into memory for fast access, similar to virtual memory.

3. How NIO Works

Java NIO consists of three core components: Channel, Buffer, Selector.

All I/O starts with a Channel; data moves between Channel and Buffer. Common channel types include FileChannel, DatagramChannel, SocketChannel, ServerSocketChannel.

A Buffer is a memory block that can be written to and read from. NIO provides buffers for all primitive types (ByteBuffer, CharBuffer, etc.).

Buffers have three key properties: capacity (fixed maximum size), position (current index), and limit (boundary for read/write). Their meanings depend on whether the buffer is in read or write mode.

capacity: maximum number of elements the buffer can hold.

position: index of the next element to read or write.

limit: in write mode, the maximum index that can be written (often equals capacity); in read mode, the index of the first element not yet read (set to position when switching to read mode).

The Selector enables a single thread to monitor multiple Channels. Channels are registered with the Selector, which blocks on select() until an event occurs, then the thread processes the ready events.

4. Java Serialization and Deserialization

Serialization converts an object into a byte sequence that can be stored or transmitted; deserialization restores the object from that byte sequence. A class must implement the marker interface Serializable to be eligible.

ObjectOutputStream.writeObject() writes an object; ObjectInputStream.readObject() reads it back.

5. Why Define serialVersionUID?

serialVersionUID identifies the version of a serialized class. During deserialization, the stored UID must match the current class UID; otherwise, an InvalidClassException is thrown, preventing incompatibility issues.

Without a defined UID, changes to the class (adding/removing fields) can cause deserialization failures.

6. Alternative Serialization Tools

JSON libraries (Jackson, Gson, Fastjson) – human‑readable, but slower than binary formats.

Protobuf – language‑agnostic binary format, compact and fast.

Thrift – high‑performance RPC framework with its own serialization.

Avro – supports JSON or binary formats, schema evolution, suited for big‑data pipelines.

7. Serializing Without JSON Libraries

Use Java’s built‑in serialization (lower performance, suitable for small projects) or third‑party libraries such as Protobuf, Thrift, Avro.

serializationNIOStreamsIO
Java Interview Crash Guide
Written by

Java Interview Crash Guide

Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.