Character Streams, BufferedReader, BufferedWriter, PrintWriter & Serialization
1. The Character Streams (Reader and Writer)
While Byte Streams (InputStream / OutputStream) read and write 8-bit raw bytes, Character Streams are designed specifically for reading and writing 16-bit Unicode text characters. They automatically translate between the internal Unicode character set and the local operating system’s character encoding (like UTF-8).
Abstract Root Classes of Character Streams:
java.io.Reader(For Reading Characters):int read(): Reads a single character (returns-1at End of File).int read(char[] cbuf): Reads characters into achararray.void close(): Closes the stream.- Concrete File Subclass:
FileReader(new FileReader("notes.txt")).
java.io.Writer(For Writing Characters):void write(int c): Writes a single character.void write(String str): Writes an entireStringdirectly!void flush()andvoid close().- Concrete File Subclass:
FileWriter(new FileWriter("notes.txt")).
2. BufferedReader and BufferedWriter (High-Speed Buffered Text I/O)
Reading or writing a file one single character at a time directly from the hard disk (FileReader / FileWriter) is slow because every call triggers a physical disk access!
To make text I/O 10x faster, Java provides BufferedReader and BufferedWriter, which create an in-memory buffer array (8 KB by default) in RAM.
notes.txtFileReader →readLine()A. BufferedReader
- Wraps around any
Reader(likeFileReaderorInputStreamReader) to buffer input and provide the super-usefulreadLine()method! - Star Method —
String readLine(): Reads an entire line of text at once and returns it as aString(returnsnullwhen the End of File is reached).
B. BufferedWriter
- Wraps around any
Writer(likeFileWriter) to buffer characters in RAM before writing them in bulk to the disk. - Star Method —
void newLine(): Writes a platform-independent line separator (\r\non Windows,\non Linux/Mac).
Complete Program: Reading & Writing Lines Using BufferedWriter & BufferedReader
import java.io.*;
public class BufferedCharacterDemo {
public static void main(String[] args) {
String file = "college.txt";
// 1. Writing multiple lines using BufferedWriter
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write("Line 1: Devi Ahilya Vishwavidyalaya (DAVV)");
bw.newLine(); // Platform-independent new line
bw.write("Line 2: Bachelor of Computer Applications (BCA)");
bw.newLine();
bw.write("Line 3: Unit 5 - Input/Output and JDBC");
System.out.println("Lines written successfully using BufferedWriter!");
} catch (IOException e) {
System.out.println(e);
}
// 2. Reading file line-by-line using BufferedReader.readLine()
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
System.out.println("\n--- Reading File Line by Line ---");
String line;
// readLine() returns null when End of File is reached
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println(e);
}
}
}
3. The PrintWriter Class
PrintWriter is the Character-Stream equivalent of PrintStream!
- Just like
PrintStream,PrintWriterprovides convenientprint(),println(), andprintf()methods for all primitive types and objects, and never throwsIOException. - Why is
PrintWriterpreferred overPrintStreamfor text files? BecausePrintWriteris a Character Stream (Writer) that properly supports 16-bit Unicode characters and international encodings (UTF-8), whereasPrintStreamis a raw Byte Stream.
PrintWriter pw = new PrintWriter(new FileWriter("invoice.txt"));
pw.println("=== CAMPUS BOOKSTORE INVOICE ===");
pw.printf("Book: %s | Price: Rs. %.2f\n", "Java Complete Reference", 650.00);
pw.close();
4. Serialization in Java (Saving & Restoring Objects)
Normally, when your Java program terminates, all objects living in Heap memory are wiped out. What if you want to save a live Java Object (e.g., a Student object with rollNo, name, cgpa) directly into a file or send it over a network, and reconstruct that exact object later?
- Serialization: The process of converting the state of a live Java Object into a linear sequence of bytes (Byte Stream) so that it can be saved to a disk file or transmitted across a network.
- Deserialization: The reverse process of reconstructing the live Java Object in memory from the saved Byte Stream.
Student s1 (Implements Serializable)ObjectOutputStream.writeObject() →student.ser (On Disk / Network)ObjectInputStream.readObject() →Student s2 in RAMKey Components of Serialization:
java.io.SerializableInterface (Marker Interface):- A class MUST implement the
Serializableinterface to allow its objects to be serialized (class Student implements Serializable). - What is a Marker Interface? An empty interface with zero methods! It simply acts as a “tag” or permission stamp telling the JVM that objects of this class are safe to serialize (otherwise JVM throws
NotSerializableException).
- A class MUST implement the
ObjectOutputStream&writeObject(Object obj): Used to serialize an object and write its bytes to a file.ObjectInputStream&readObject(): Used to deserialize bytes from a file and return the reconstructedObject.- The
transientKeyword (Preventing a Field from Being Serialized): If a class has a sensitive field likepasswordoratmPinthat you do NOT want to save to the file during serialization, declare that variable astransient(transient String password;). When deserialized, atransientfield receives its default value (nullor0).
Complete Program: Serialization & Deserialization with transient
import java.io.*;
// Step 1: Class MUST implement Serializable (Marker Interface)
class Student implements Serializable {
int rollNo;
String name;
transient String password; // 'transient' field will NOT be saved to the file!
public Student(int rollNo, String name, String password) {
this.rollNo = rollNo;
this.name = name;
this.password = password;
}
}
public class SerializationDemo {
public static void main(String[] args) {
String fileName = "student_data.ser";
// PART 1: SERIALIZATION (Saving Object -> File)
try {
Student s1 = new Student(101, "Ishaan Verma", "Secret@123");
FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(s1); // Serializes s1 into bytes
oos.close();
fos.close();
System.out.println("Object Serialized and saved to " + fileName);
} catch (Exception e) {
System.out.println(e);
}
// PART 2: DESERIALIZATION (Restoring File -> Object)
try {
FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis);
// readObject() returns Object, so type-cast back to (Student)
Student restored = (Student) ois.readObject();
ois.close();
fis.close();
System.out.println("\n--- Deserialized Object Details ---");
System.out.println("Roll No : " + restored.rollNo);
System.out.println("Name : " + restored.name);
System.out.println("Password: " + restored.password); // Prints null (transient!)
} catch (Exception e) {
System.out.println(e);
}
}
}
Output:
Object Serialized and saved to student_data.ser
--- Deserialized Object Details ---
Roll No : 101
Name : Ishaan Verma
Password: null
💡 Exam Preparation Tips for DAVV BCA
- Serialization is an 8-mark favorite in Unit 5! Always mention four key terms in your answer:
Serializable(Marker Interface)ObjectOutputStream→writeObject()ObjectInputStream→readObject()transientkeyword (for skipping sensitive fields like passwords).