Advanced Java ProgrammingUnit 1211 min read
Serialization, I/O Streams, File Handling & Advanced Data Persistence
Unit 12 of Advanced Java Programming covers serialization (object persistence), advanced I/O streams (byte/character streams, buffering, serialization streams), file handling (reading/writing files, random access), and performance optimizations like buffering and compression. Students learn how to persist Java objects,
TAKEAWAYS:
- Understand serialization (converting objects to byte streams) and its role in saving/loading objects to/from files or networks.
- Master I/O streams (byte vs. character, buffered vs. unbuffered) and their hierarchy in Java’s
java.iopackage. - Learn file handling techniques (reading/writing text/binary files, random access) with practical examples like logs or databases.
- Compare serialization vs. JSON/XML for data persistence, including security and compatibility trade-offs.
- Optimize I/O performance using buffering, compression (GZIP), and object streams.
- Apply exception handling for file operations (e.g.,
FileNotFoundException,IOException).
1. Serialization: Saving and Loading Objects
Serialization is the process of converting an object’s state (data) into a byte stream to store it or transmit it over a network. Java provides built-in support via java.io.Serializable interface.
How Serialization Works
- An object implements
Serializable. ObjectOutputStreamconverts the object to bytes.- Bytes are written to a file/network.
ObjectInputStreamreconstructs the object from bytes.
import java.io.*;
class Student implements Serializable {
private static final long serialVersionUID = 1L;
String name;
int rollNo;
// Constructor, getters, setters
}
public class SerializeDemo {
public static void main(String[] args) {
Student s = new Student("Rohan", 101);
try {
// Serialize to file
FileOutputStream fos = new FileOutputStream("student.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(s);
oos.close();
fos.close();
System.out.println("Serialized!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
State After Serialization
graph LR
A["Student Object (s)"]
B["ObjectOutputStream"]
C["File: student.ser (byte stream)"]
A -->|"writeObject()"| B
B -->|"write()"| CDeserialization (Loading Object)
try {
FileInputStream fis = new FileInputStream("student.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Student loadedStudent = (Student) ois.readObject();
System.out.println("Name: " + loadedStudent.name);
ois.close();
fis.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
Key Points
serialVersionUID: Ensures version compatibility. Without it, Java generates one automatically.- Transient Fields: Marked with
transientkeyword, these fields are ignored during serialization. - Security: Serialization can be a security risk (e.g., malicious object reconstruction). Use
ObjectInputFilterto mitigate.
Real-World Example: eSewa Transaction Logs
eSewa stores transaction records (e.g., user IDs, amounts) as serialized objects in a database. This allows:
- Fast retrieval of past transactions.
- Efficient storage (binary format is compact).
- Cross-platform compatibility (Java objects can be read anywhere).
2. I/O Streams: Byte vs. Character Streams
Java’s java.io package provides two types of streams:
- Byte Streams (
InputStream,OutputStream): Handle raw bytes (e.g., images, binary files). - Character Streams (
Reader,Writer): Handle text (Unicode characters).
Stream Hierarchy
classDiagram
class InputStream
class OutputStream
class Reader
class Writer
class FileInputStream <|-- InputStream
class FileOutputStream <|-- OutputStream
class FileReader <|-- Reader
class FileWriter <|-- Writer
class BufferedInputStream <|-- InputStream
class BufferedOutputStream <|-- OutputStream
class BufferedReader <|-- Reader
class BufferedWriter <|-- Writer
class ObjectOutputStream <|-- OutputStream
class ObjectInputStream <|-- InputStreamExample: Reading a Text File
try (FileReader fr = new FileReader("data.txt");
BufferedReader br = new BufferedReader(fr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
State After Reading a File
graph LR
A["File: data.txt"] -->|"FileReader"| B["BufferedReader"]
B -->|"readLine()"| C["Line 1: Hello"]
B -->|"readLine()"| D["Line 2: World"]Buffered Streams for Performance
- BufferedInputStream/BufferedOutputStream: Reduce I/O operations by buffering data in memory.
- BufferedReader/BufferedWriter: Improve text reading/writing efficiency.
Example: Writing to a File with Buffering
try (FileWriter fw = new FileWriter("output.txt");
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write("Buffered I/O is efficient!");
bw.newLine();
bw.write("Java makes it easy.");
} catch (IOException e) {
e.printStackTrace();
}
3. File Handling: Reading and Writing Files
Common File Operations
| Operation | Byte Stream Example | Character Stream Example |
|---|---|---|
| Read File | FileInputStream |
FileReader |
| Write File | FileOutputStream |
FileWriter |
| Append to File | FileOutputStream(true) |
FileWriter(true) |
| Random Access | RandomAccessFile |
N/A |
Example: Copying a File
public static void copyFile(String src, String dest) throws IOException {
try (FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
}
State After Copying a File
graph LR
A["Source File (src.txt)"] -->|"FileInputStream"| B["Buffer (1KB chunks)"]
B -->|"FileOutputStream"| C["Destination File (dest.txt)"]Real-World Example: Daraz Order Processing
Daraz uses file I/O to:
- Log orders in
orders.log(appended daily). - Store product images in binary format (
product_images/). - Read/write inventory files (
inventory.dat) for stock updates.
Example: Logging an Order
try (FileWriter fw = new FileWriter("orders.log", true);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write("Order#123: User=John, Product=Laptop, Amount=50000");
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
}
4. Random Access Files
RandomAccessFile allows reading/writing at any position in a file (useful for databases or large logs).
Example: Updating a Record in a File
try (RandomAccessFile raf = new RandomAccessFile("data.dat", "rw")) {
// Seek to position 100 (bytes)
raf.seek(100);
raf.writeUTF("Updated Value");
} catch (IOException e) {
e.printStackTrace();
}
State After Random Access Update
graph LR
A["File: data.dat"] -->|"seek(100)"| B["Position 100"]
B -->|"writeUTF()"| C["Updated Value"]Real-World Example: NTC Electricity Bill Updates
NTC stores customer bills in a binary file (bills.dat). When a user pays, the system:
- Opens
bills.datwithRandomAccessFile. - Seeks to the customer’s record (e.g., position 5000).
- Updates the
paidflag totrue.
5. Serialization vs. JSON/XML
| Feature | Serialization | JSON/XML |
|---|---|---|
| Format | Binary | Text (human-readable) |
| Portability | Java-only | Cross-language (Python, JS, etc.) |
| Security | Risk of malicious object injection | Safer (parsed as text) |
| Performance | Faster (binary) | Slower (text parsing) |
| Use Case | Internal Java apps (e.g., caches) | Web APIs, config files |
Example: JSON Alternative (Using org.json)
import org.json.*;
JSONObject student = new JSONObject();
student.put("name", "Rohan");
student.put("rollNo", 101);
String jsonString = student.toString(); // '{"name":"Rohan","rollNo":101}'
6. Advanced I/O: Compression and Performance
Compressing Files with GZIP
try (FileOutputStream fos = new FileOutputStream("data.gz");
GZIPOutputStream gzos = new GZIPOutputStream(fos);
FileInputStream fis = new FileInputStream("data.txt")) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
gzos.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
Real-World Example: WhatsApp Media Storage
WhatsApp compresses images/videos using algorithms like GZIP or ZIP before sending them to save bandwidth. This reduces file size by ~70% for photos.
7. Exception Handling in I/O
Common exceptions:
FileNotFoundException: File does not exist.IOException: General I/O errors (e.g., disk full).ClassNotFoundException: During deserialization (invalid class).
Example: Handling File Errors
try {
FileInputStream fis = new FileInputStream("nonexistent.txt");
} catch (FileNotFoundException e) {
System.err.println("File not found: " + e.getMessage());
} catch (IOException e) {
System.err.println("I/O Error: " + e.getMessage());
}
In the Real World
eSewa Transaction Records
- Idea Used: Serialization + File I/O
- How: Transactions are serialized into
transactions.serfor fast retrieval. During audits, eSewa deserializes these objects to verify amounts.
Khalti Payment Logs
- Idea Used: Buffered Character Streams
- How: Khalti appends payment logs (
payments.log) usingBufferedWriterto minimize disk writes, improving speed.
Daraz Inventory Management
- Idea Used: Random Access Files
- How: Daraz uses
RandomAccessFileto update stock levels ininventory.datwithout rewriting the entire file, saving time.
Ncell Customer Data Backup
- Idea Used: Compression (GZIP)
- How: Nightly backups of customer data are compressed with GZIP to reduce storage costs and backup time.
Exam Tip
Serialization Questions:
- Always include
serialVersionUIDin your code. - Explain why
transientfields are excluded. - Compare serialization with JSON/XML in terms of speed and portability.
- Always include
I/O Streams:
- Draw the stream hierarchy (byte vs. character, buffered vs. unbuffered).
- Show the state of buffers after operations (e.g., reading a file line by line).
File Handling:
- For file copying, explain the role of buffers (e.g., 1KB chunks).
- In random access examples, show the
seek()position and updated data.
Real-World Scenarios:
- Relate file operations to apps like eSewa (logs), Daraz (inventory), or Ncell (backups).
- For compression, mention bandwidth savings (e.g., WhatsApp, YouTube).
Common Pitfalls:
- Forgetting to close streams (use
try-with-resources). - Not handling
IOExceptionorClassNotFoundException. - Serializing non-serializable objects (e.g.,
ArrayListwithout implementingSerializable).
- Forgetting to close streams (use
Practice: Implement a program that:
- Serializes a
BankAccountobject to a file. - Uses
RandomAccessFileto update the balance. - Compresses the file with GZIP for backup.
Based on the TU BSc CSIT syllabus for Advanced Java Programming (CSC409), unit 12.
Discussion
Loading…