Fundamentals 11 min read

Understanding Java I/O Streams: Concepts, Classifications, and Code Examples

This article explains the concept of Java I/O streams, their classifications, and provides detailed code examples for InputStream, FileInputStream, FileOutputStream, BufferedOutputStream, and DataOutputStream, illustrating how to read, write, and manage resources effectively.

Java Captain
Java Captain
Java Captain
Understanding Java I/O Streams: Concepts, Classifications, and Code Examples

Concept of Streams

Java programs use streams to perform input and output operations. A stream is an abstract representation of a source or destination of data, linking Java I/O to physical devices such as files, keyboards, or network sockets, while providing a uniform API.

An input stream moves data from an external source (e.g., disk file, network) into the program or memory, whereas an output stream moves data in the opposite direction. External media can include local or remote files, database connections, TCP/UDP/HTTP communication, inter‑process communication, and hardware devices.

Classification of Streams

Streams can be classified by:

Function: input streams vs. output streams

Structure: byte streams vs. character streams

Source: node streams (directly connected to a data source) vs. filter streams (wrap a node stream to add functionality)

Byte streams (InputStream/OutputStream) handle raw binary data, while character streams (Reader/Writer) provide convenient methods for text processing.

InputStream

InputStream is an abstract class defining three overloaded read methods; only the single‑byte read() method is abstract, and the other two delegate to it. Subclasses therefore need to implement only the basic method.

Logical Steps for Reading/Writing Data

1. Open a stream 2. While more data is available 3. Read or write data 4. Close the stream

1. FileInputStream Example

public static void main(String[] args) throws IOException {
    InputStream is = new FileInputStream("c:/test.txt");
    int length = 0;
    byte[] buffer = new byte[20];
    while (-1 != (length = is.read(buffer, 0, 20))) {
        String str = new String(buffer, 0, length);
        System.out.print(str);
    }
    is.close();
}

The program reads a file in 20‑byte chunks, prints each chunk, and stops when read returns -1.

2. FileOutputStream Example

public static void main(String[] args) throws IOException {
    OutputStream os = new FileOutputStream("c:/test1.txt");
    String str = "中国移动手机阅读";
    byte[] b = str.getBytes();
    os.write(b);
    os.close();
}

This demo writes a string to a file, creating the file if it does not exist or overwriting it if it does. To append instead of overwriting, use the constructor new FileOutputStream("c:/test.txt", true) .

OutputStream os = new FileOutputStream("c:/test.txt", true);
String str = "注册用户6亿";
byte[] b = str.getBytes();
os.write(b);
os.close();

With the second argument set to true , data is appended to the end of the file.

3. BufferedOutputStream Example

Buffered streams reduce the number of physical I/O operations by writing data to an in‑memory buffer first; the buffer is flushed when full, when close() is called, or when flush() is invoked.

public static void main(String[] args) throws IOException {
    OutputStream os = new FileOutputStream("c:/test.txt");
    OutputStream bs = new BufferedOutputStream(os);
    byte[] buffer = "中国移动阅读基地".getBytes();
    bs.write(buffer);
    bs.close();
    os.close();
}

If close() is omitted, data remains in the buffer and is not written to the file.

4. DataOutputStream Example

DataOutputStream allows writing Java primitive types in a portable binary format.

public static void main(String[] args) throws IOException {
    DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(
            new FileOutputStream("c:/data.txt")));
    byte b = 4;
    char c = 'c';
    int i = 12;
    float f = 3.3f;
    dos.writeByte(b);
    dos.writeChar(c);
    dos.writeInt(i);
    dos.writeFloat(f);
    dos.close();
}

The corresponding DataInputStream must read the values in the same order:

DataInputStream dis = new DataInputStream(new BufferedInputStream(
        new FileInputStream("c:/data.txt")));
System.out.println(dis.readByte());
System.out.println(dis.readChar());
System.out.println(dis.readInt());
System.out.println(dis.readFloat());
dis.close();

Output: 4, c, 12, 3.3. The read order must match the write order to avoid corrupted data.

JavaI/OstreamsFileIOInputStreamOutputStream
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login 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.