Object Oriented Programming with JavaUnit 714 min read
File I/O in Java: Streams, Files, and Serialization
Unit 7 of Object Oriented Programming with Java covers file handling techniques in Java, including stream types (byte/character), file operations (read/write), serialization, and best practices for robust I/O handling with error management.
TAKEAWAYS:
- Understand stream types (input/output, byte/character) and their classes (
FileInputStream,BufferedReader, etc.) with clear use cases. - Master file operations (create, read, write, delete) using
FileandFileWriter/FileReaderwith proper resource management. - Learn serialization to persist objects (
Serializableinterface,ObjectOutputStream) and its security implications. - Compare buffered vs. non-buffered streams for performance optimization.
- Handle exceptions (
IOException,FileNotFoundException) usingtry-with-resourcesfor automatic cleanup. - Apply real-world scenarios like logging, data backup, and configuration files in Java applications.
1. Introduction to File I/O in Java
File I/O (Input/Output) allows Java programs to interact with external files and streams. This is essential for:
- Storing data persistently (e.g., user profiles, transaction logs).
- Reading configuration files (e.g.,
config.propertiesin apps like Khalti or Pathao). - Processing large datasets (e.g., NTC or NEPSE stock data).
Java provides two main approaches:
- Stream-based I/O: Uses
InputStream/OutputStream(byte streams) andReader/Writer(character streams). - File-based I/O: Uses
Fileclass for file metadata and operations.
2. Stream Types in Java
Streams are sequences of data read from or written to a source/destination. They are categorized as:
A. Byte Streams vs. Character Streams
| Byte Streams | Character Streams |
|---|---|
Handles raw bytes (InputStream, OutputStream). |
Handles Unicode characters (Reader, Writer). |
| Used for binary files (images, executables). | Used for text files (.txt, .csv). |
Example: FileInputStream, FileOutputStream. |
Example: FileReader, FileWriter. |
Why it matters:
- Ncell’s billing system uses byte streams to read binary data from SIM cards.
- Daraz’s order processing uses character streams to log text-based order details in
.csvfiles.
Visual: Stream Hierarchy
classDiagram
class InputStream {
+int read()
}
class OutputStream {
+void write(int b)
}
class Reader {
+int read()
}
class Writer {
+void write(int c)
}
InputStream <|-- FileInputStream
OutputStream <|-- FileOutputStream
Reader <|-- FileReader
Writer <|-- FileWriter
FileInputStream --> BufferedInputStream
FileOutputStream --> BufferedOutputStream
FileReader --> BufferedReader
FileWriter --> BufferedWriter3. File Operations
The File class (in java.io) represents file/directory metadata but cannot read/write data directly. Use streams for that.
Key Methods
| Method | Description |
|---|---|
File(String path) |
Creates a File object. |
boolean createNewFile() |
Creates a new empty file. |
boolean delete() |
Deletes the file. |
boolean exists() |
Checks if the file exists. |
long length() |
Returns file size in bytes. |
String[] list() |
Lists files in a directory. |
Example: Create and Write to a File
import java.io.FileWriter;
import java.io.IOException;
public class FileDemo {
public static void main(String[] args) {
try (FileWriter writer = new FileWriter("data.txt")) {
writer.write("Hello, TU Students!\n");
writer.write("File I/O is easy with Java.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Trace:
| Step | Action | File Content (data.txt) |
|---|---|---|
| 1 | FileWriter opens data.txt. |
(Empty) |
| 2 | write("Hello...") |
Hello, TU Students! |
| 3 | write("File I/O...") |
Hello, TU Students!\nFile I/O... |
| 4 | try-with-resources closes file. |
(Content preserved) |
Real-World Tie-In:
- eSewa’s transaction logs are written to files using
FileWriterto record payments securely.
4. Buffered Streams for Performance
Buffered streams reduce I/O operations by reading/writing data in chunks.
sequenceDiagram
participant User
participant BufferedWriter
participant FileWriter
participant data_txt
User->>BufferedWriter: write("Buffered I/O is efficient!")
BufferedWriter->>FileWriter: write()
FileWriter->>data_txt: Buffer fills
User->>BufferedWriter: newLine()
BufferedWriter->>FileWriter: write("\n")
User->>BufferedWriter: close()
BufferedWriter->>FileWriter: flush()
FileWriter->>data_txt: Writes to file
alt Buffer full
BufferedWriter->>FileWriter: flush()
endBufferedWriter flush mechanism during write operationsComparison: Buffered vs. Non-Buffered
| Feature | FileWriter (Non-Buffered) |
BufferedWriter (Buffered) |
|---|---|---|
| Speed | Slower (1 byte at a time). | Faster (buffers data). |
| Memory Usage | Low. | Higher (temporary buffer). |
| Use Case | Small files. | Large files (e.g., logs). |
Example: BufferedWriter
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedDemo {
public static void main(String[] args) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("buffered.txt"))) {
writer.write("Buffered I/O is efficient!\n");
writer.newLine(); // Adds OS-specific newline.
} catch (IOException e) {
e.printStackTrace();
}
}
}
Trace:
| Step | Action | Buffer State | File Content (buffered.txt) |
|---|---|---|---|
| 1 | BufferedWriter initializes. |
Empty buffer. | (Empty) |
| 2 | write("Buffered...") |
Buffer: "Buffered..." |
(Empty) |
| 3 | newLine() |
Buffer: "Buffered...\n" |
(Empty) |
| 4 | close() flushes buffer. |
Empty buffer. | Buffered...\n |
Real-World Tie-In:
- NEPSE’s stock data processing uses
BufferedReaderto efficiently read large.csvfiles of daily trades.
5. Reading Files
A. Reading Text Files (BufferedReader)
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFileDemo {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Trace:
| Step | Action | reader.readLine() |
Output |
|---|---|---|---|
| 1 | Opens data.txt. |
— | — |
| 2 | readLine() |
"Hello, TU..." |
Hello, TU Students! |
| 3 | readLine() |
"File I/O..." |
File I/O is easy... |
| 4 | readLine() returns null. |
null |
(Loop ends) |
B. Reading Binary Files (FileInputStream)
import java.io.FileInputStream;
import java.io.IOException;
public class BinaryReadDemo {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("image.png")) {
int data;
while ((data = fis.read()) != -1) {
// Process binary data (e.g., write to another file).
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Real-World Tie-In:
- Pathao’s ride data is stored in binary format for faster access during peak hours.
6. Serialization: Saving Objects to Files
Serialization converts objects into byte streams for storage/transmission. Use the Serializable interface.
Example: Serializing a Student Object
import java.io.*;
class Student implements Serializable {
private String name;
private int rollNo;
public Student(String name, int rollNo) {
this.name = name;
this.rollNo = rollNo;
}
}
public class SerializationDemo {
public static void main(String[] args) {
Student student = new Student("Ramesh", 101);
// Serialize
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.ser"))) {
oos.writeObject(student);
} catch (IOException e) {
e.printStackTrace();
}
// Deserialize
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student.ser"))) {
Student loadedStudent = (Student) ois.readObject();
System.out.println("Loaded: " + loadedStudent.name);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Trace:
| Step | Action | File (student.ser) |
Object State |
|---|---|---|---|
| 1 | writeObject(student) |
Binary data written. | student serialized. |
| 2 | readObject() |
Binary data read. | loadedStudent restored. |
Real-World Tie-In:
- Khalti’s user session data is serialized to temporarily store user login details during transactions.
7. Exception Handling in File I/O
Common exceptions:
FileNotFoundException: File does not exist.IOException: General I/O errors (e.g., disk full).ClassNotFoundException: During deserialization (if class definition is missing).
Best Practice: Use try-with-resources to auto-close streams.
try (Resource res = new Resource()) {
// Code
} catch (Exception e) {
e.printStackTrace();
}
8. File Handling Best Practices
- Always close resources: Use
try-with-resourcesorfinallyblocks. - Handle exceptions: Never ignore
IOException. - Use buffered streams: For large files, improve performance.
- Validate paths: Check
File.exists()before operations. - Security: Avoid deserializing untrusted data (risk of
InvalidClassException).
In the Real World
eSewa:
- Uses
FileWriterto log transactions intransactions.logfor auditing. - Example: Every payment is appended to the file with a timestamp.
- Uses
NTC’s Billing System:
- Employs
BufferedReaderto parse large.csvfiles of customer usage data. - Example: Reads 10,000 records in seconds for monthly billing.
- Employs
Pathao’s Driver App:
- Serializes driver location data (
Driverobjects) todriver.serfor quick recovery after crashes. - Example: If the app crashes, the last known location is restored from the file.
- Serializes driver location data (
Exam Tip
Stream Types:
- Know when to use byte streams (binary files) vs. character streams (text files).
- Example question: "Which stream would you use to read a
.jpgfile?" →FileInputStream.
File Operations:
- Memorize
Fileclass methods (exists(),delete(), etc.). - Example question: "How do you check if a file exists in Java?" →
file.exists().
- Memorize
Serialization:
- Understand
SerializableandObjectOutputStream. - Example question: "What happens if a class does not implement
Serializable?" →NotSerializableException.
- Understand
Error Handling:
- Always use
try-with-resourcesin exams. - Example question: "Write code to safely read a file." → Include
try-with-resources.
- Always use
Performance:
- Compare buffered vs. non-buffered streams.
- Example question: "Why is
BufferedReaderfaster thanFileReader?" → Reduces system calls.
Visual Summary: File I/O Workflow
flowchart TD
A["Program"] --> B["Choose Stream Type<br/>(Byte/Character)"]
B -->|"Byte"| C["FileInputStream<br/>FileOutputStream"]
B -->|"Character"| D["FileReader<br/>FileWriter"]
C --> E["BufferedInputStream<br/>BufferedOutputStream"]
D --> F["BufferedReader<br/>BufferedWriter"]
E --> G["Read/Write Binary Data"]
F --> H["Read/Write Text Data"]
G --> I["File Operations<br/>(create, delete, etc.)"]
H --> I
I --> J["Handle Exceptions<br/>(IOException)"]
J --> K["Close Resources<br/>(try-with-resources)"]In the real world
- eSewa’s transaction logs: Uses
BufferedWriterto efficiently write thousands of daily transactions in binary format (byte streams) for secure storage and quick retrieval. - NEPSE stock data processing: Employs
BufferedReaderto read large.csvfiles (character streams) of daily trade data, reducing I/O overhead for real-time analysis. - Ncell’s SIM card data: Leverages byte streams (
FileInputStream) to read binary data from SIM cards for billing and customer profile management.
Based on the TU BIM syllabus for Object Oriented Programming with Java (IT234), unit 7.
Discussion
Loading…