Java Core: File I/O and Serialization - Reading & Writing Files
This document covers reading and writing files in Java, focusing on core concepts and common approaches. It also touches upon serialization.
1. Basic File I/O Concepts
- Streams: Java uses streams to perform I/O operations. Streams are sequences of data elements made available over time.
- Input Stream: Reads data from a source (e.g., a file, network connection).
- Output Stream: Writes data to a destination (e.g., a file, console).
- Readers & Writers: Character-oriented streams. Useful for text files.
- Byte Streams: Deal with raw bytes. Useful for binary files (images, audio, etc.).
- File Class: Represents a file or directory path. Provides methods for creating, deleting, renaming, and getting information about files.
2. Reading Files
Here's a breakdown of common methods for reading files:
a) Using FileReader and BufferedReader (for text files):
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFileExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("myFile.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
}
}
- Explanation:
FileReaderopens the file for reading.BufferedReaderprovides buffering for efficient reading, reading lines at a time.reader.readLine()reads a single line from the file. Returnsnullwhen the end of the file is reached.- Try-with-resources: The
try (...)block ensures that thereaderis automatically closed, even if exceptions occur. This is highly recommended to prevent resource leaks.
b) Using FileInputStream and InputStreamReader (for text files, more control):
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
public class ReadFileExample2 {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("myFile.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8")) { // Specify encoding!
int character;
while ((character = isr.read()) != -1) {
System.out.print((char) character);
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
}
}
- Explanation:
FileInputStreamopens the file for reading as a byte stream.InputStreamReaderconverts the byte stream to a character stream, allowing you to read characters. Important: Specify the character encoding (e.g., "UTF-8") to avoid potential issues with different character sets.isr.read()reads a single character as an integer. Returns-1when the end of the file is reached.
c) Using FileInputStream (for binary files):
import java.io.FileInputStream;
import java.io.IOException;
public class ReadBinaryFileExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("myImage.jpg")) {
byte[] buffer = new byte[1024]; // Read in chunks
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
// Process the bytes (e.g., write to another file, display image)
System.out.write(buffer, 0, bytesRead); // Example: write to console
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
}
}
- Explanation:
FileInputStreamopens the file for reading as a byte stream.- A
byte[]buffer is used to read data in chunks. fis.read(buffer)reads up tobuffer.lengthbytes from the file into the buffer. Returns the number of bytes actually read, or-1at the end of the file.- The
bytesReadvariable indicates how many bytes were actually read in the last operation.
3. Writing Files
a) Using FileWriter and BufferedWriter (for text files):
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class WriteFileExample {
public static void main(String[] args) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
writer.write("This is the first line.\n");
writer.write("This is the second line.\n");
writer.write("And this is the third line.");
} catch (IOException e) {
System.err.println("Error writing to file: " + e.getMessage());
}
}
}
- Explanation:
FileWriteropens the file for writing. If the file exists, it will be overwritten.BufferedWriterprovides buffering for efficient writing.writer.write()writes a string to the file.\nrepresents a newline character.- Try-with-resources: Ensures the writer is closed.
b) Using FileOutputStream (for binary files):
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteBinaryFileExample {
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("output.jpg")) {
byte[] data = {0x01, 0x02, 0x03, 0x04}; // Example binary data
fos.write(data);
} catch (IOException e) {
System.err.println("Error writing to file: " + e.getMessage());
}
}
}
- Explanation:
FileOutputStreamopens the file for writing as a byte stream. If the file exists, it will be overwritten.fos.write(data)writes the byte arraydatato the file.
c) Appending to a File:
To append to an existing file instead of overwriting it, use the constructor that takes a boolean argument:
FileWriter(String fileName, boolean append)FileOutputStream(String fileName, boolean append)
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt", true))) { // true for append
writer.write("This line is appended.\n");
}
4. Serialization
Serialization is the process of converting an object into a byte stream, which can then be saved to a file or transmitted over a network. Deserialization is the reverse process.
a) Serializing an Object:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializationExample {
public static void main(String[] args) {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.ser"))) {
MyClass obj = new MyClass("Hello", 123);
oos.writeObject(obj);
System.out.println("Object serialized to object.ser");
} catch (IOException e) {
System.err.println("Error serializing object: " + e.getMessage());
}
}
}
class MyClass implements java.io.Serializable {
String message;
int number;
public MyClass(String message, int number) {
this.message = message;
this.number = number;
}
}
- Explanation:
- The class
MyClassmust implement thejava.io.Serializableinterface. ObjectOutputStreamis used to serialize objects.oos.writeObject(obj)writes the objectobjto the file.
- The class
b) Deserializing an Object:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserializationExample {
public static void main(String[] args) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.ser"))) {
MyClass obj = (MyClass) ois.readObject();
System.out.println("Object deserialized: " + obj.message + ", " + obj.number);
} catch (IOException |