Chapter 4 3 min read
Save

Java Input Output

Object Oriented Programming in Java · BCA · Updated Apr 15, 2026

Table of Contents

Introduction

Input and output (I/O) is how a program communicates with the outside world — reading from the keyboard, writing to the screen, reading and writing files, sending data over the network. Java's I/O facilities are defined primarily in the java.io package, with higher-level non-blocking features added later in java.nio.

Streams

All Java I/O is built on the concept of a stream — a sequence of bytes or characters flowing from a source to a destination. Streams are one-way: a byte stream is either an InputStream (source) or an OutputStream (sink). Java provides two parallel hierarchies: byte streams for binary data (images, audio, class files) rooted at InputStream/OutputStream, and character streams for text data rooted at Reader/Writer. Character streams automatically handle character encoding (UTF-8, UTF-16, etc.) and are preferred for text.

Standard Streams

Three standard streams are always open when a Java program runs: System.in (keyboard), System.out (console), and System.err (error output). System.out.println() is the most-used I/O call in Java.

Reading from Keyboard

import java.io.*;
public class Echo {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Enter your name: ");
        String name = br.readLine();
        System.out.println("Hello, " + name);
    }
}

The modern alternative is java.util.Scanner, which wraps System.in and provides type-safe parsing methods such as nextInt(), nextDouble(), and nextLine().

File I/O with Byte Streams

try (FileInputStream in = new FileInputStream("input.bin");
     FileOutputStream out = new FileOutputStream("output.bin")) {
    int b;
    while ((b = in.read()) != -1) out.write(b);
}

The try-with-resources statement automatically closes the streams when the block exits, even if an exception is thrown.

File I/O with Character Streams

try (FileReader fr = new FileReader("text.txt");
     BufferedReader br = new BufferedReader(fr);
     FileWriter fw = new FileWriter("copy.txt");
     BufferedWriter bw = new BufferedWriter(fw)) {
    String line;
    while ((line = br.readLine()) != null) {
        bw.write(line);
        bw.newLine();
    }
}

Buffered Streams

BufferedReader and BufferedWriter wrap another reader/writer and add an internal buffer, dramatically improving performance for small reads. BufferedReader.readLine() returns an entire line at once. The analogous byte-stream classes are BufferedInputStream and BufferedOutputStream.

PrintWriter

PrintWriter provides println(), printf(), and format() methods for formatted output. Unlike System.out, it can be attached to any Writer — so you can write formatted text to a file just as easily as to the console.

try (PrintWriter pw = new PrintWriter(new FileWriter("report.txt"))) {
    pw.printf("Average = %.2f%n", 87.345);
}

File Class

The java.io.File class represents a file or directory in the filesystem. Useful methods include exists(), length(), isDirectory(), listFiles(), mkdirs(), delete(), and renameTo(). The newer java.nio.file.Path and Files classes (Java 7+) provide a more modern API.

Sequential vs Random Access

A FileInputStream reads bytes in sequence from start to finish. For random access — reading or writing any position in a file — use RandomAccessFile, which supports seek(position) and bidirectional reading and writing.

try (RandomAccessFile raf = new RandomAccessFile("data.bin", "rw")) {
    raf.seek(100);
    raf.writeInt(42);
    raf.seek(100);
    System.out.println(raf.readInt());
}

Serialization

Java serialization converts an object graph into a byte stream that can be written to disk or sent over a network, then later reconstructed into an equivalent object. A class is serializable if it implements java.io.Serializable. Use ObjectOutputStream to write and ObjectInputStream to read.

Summary

Java I/O is built around streams: byte streams for binary data, character streams for text. Wrap base streams with buffered wrappers for performance, use try-with-resources for cleanup, and reach for RandomAccessFile or java.nio when the standard streams are not enough.

Important Questions

  1. Differentiate byte streams from character streams with examples.
  2. Write a Java program to read a file line by line using BufferedReader.
  3. Explain the purpose of try-with-resources.
  4. Compare Scanner and BufferedReader.
  5. What is RandomAccessFile? When would you use it instead of FileInputStream?
  6. Write a program that copies a binary file using byte streams.
  7. Explain Java serialization with an example.
  8. List five useful methods of the File class.

Related Notes

Discussion

0 comments

Join the discussion

Log in to share your thoughts and help fellow students.

Log in to comment

No comments yet. Be the first to share your thoughts!