5.3 Text I/O vs.
Binary I/O, Binary I/O Classes Motivations and
Benefits Defining Generic Classes and Interfaces
1. Text I/O vs. Binary I/O
Java provides two main ways to handle file input and output: Text I/O and Binary I/O.
Feature Text I/O Binary I/O
Data Type Reads/writes text (characters) Reads/writes raw bytes
Uses character encoding (e.g.,
Encoding No encoding, stores raw binary data
UTF-8)
Slower (encoding/decoding
Speed Faster (direct byte storage)
overhead)
Usage For text files (e.g., .txt, .csv) For binary files (e.g., .jpg, .mp3, .exe)
Java BufferedReader, BufferedWriter, FileInputStream, FileOutputStream,
Classes FileReader, FileWriter ObjectInputStream, ObjectOutputStream
Example of Text I/O
import java.io.*;
public class TextIOExample {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("textfile.txt"))) {
bw.write("Hello, this is a text file.");
bw.newLine();
bw.write("Second line of text.");
} catch (IOException e) {
System.out.println("Error writing file: " + e.getMessage());
}
try (BufferedReader br = new BufferedReader(new FileReader("textfile.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
}
}
}
✅ Output (from file):
Hello, this is a text file.
Second line of text.
Example of Binary I/O
import java.io.*;
public class BinaryIOExample {
public static void main(String[] args) {
// Writing binary data
try (FileOutputStream fos = new FileOutputStream("binaryfile.dat")) {
fos.write(100); // Writes a single byte (value 100)
fos.write(200); // Writes another byte
} catch (IOException e) {
System.out.println("Error writing binary file: " + e.getMessage());
}
// Reading binary data
try (FileInputStream fis = new FileInputStream("binaryfile.dat")) {
int value;
while ((value = fis.read()) != -1) {
System.out.print(value + " ");
}
} catch (IOException e) {
System.out.println("Error reading binary file: " + e.getMessage());
}
}
}
✅ Output (raw binary data read from file):
100 200
2. Binary I/O Classes: Motivation and Benefits
Motivation for Using Binary I/O
✔ Efficient storage – No encoding overhead, direct byte storage.
✔ Faster processing – No need for character conversion.
✔ Handles all types of data – Can store text, images, audio, and video files.
✔ Preserves data integrity – No risk of encoding corruption.
Key Binary I/O Classes
Class Description
FileInputStream / FileOutputStream Reads/writes raw byte streams from/to files.
Reads/writes primitive data types (e.g., int,
DataInputStream / DataOutputStream
double).
ObjectInputStream /
Reads/writes Java objects (serialization).
ObjectOutputStream
Example of Object I/O (Serialization)
import java.io.*;
// A serializable class
class Person implements Serializable {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public class ObjectIOExample {
public static void main(String[] args) {
// Writing object to file
try (ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream("person.dat"))) {
Person p = new Person("Alice", 25);
oos.writeObject(p);
} catch (IOException e) {
System.out.println("Error writing object: " + e.getMessage());
}
// Reading object from file
try (ObjectInputStream ois = new ObjectInputStream(new
FileInputStream("person.dat"))) {
Person p = (Person) ois.readObject();
System.out.println("Person: " + p.name + ", Age: " + p.age);
} catch (IOException | ClassNotFoundException e) {
System.out.println("Error reading object: " + e.getMessage());
}
}
}
✅ Output:
Person: Alice, Age: 25
3. Defining Generic Classes and Interfaces
Generics allow writing flexible and type-safe code by defining classes and interfaces
with type parameters.
Advantages of Generics
✔ Type safety – Prevents ClassCastException at runtime.
✔ Code reusability – Single class for multiple data types.
✔ Performance – Eliminates need for explicit casting.
Example of a Generic Class
// Generic class with a type parameter <T>
class Box<T> {
private T value;
void setValue(T value) {
this.value = value;
}
T getValue() {
return value;
}
}
public class GenericClassExample {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.setValue(10);
System.out.println("Integer Value: " + intBox.getValue());
Box<String> strBox = new Box<>();
strBox.setValue("Hello");
System.out.println("String Value: " + strBox.getValue());
}
}
✅ Output:
vbnet
CopyEdit
Integer Value: 10
String Value: Hello
4. Generic Interfaces
A generic interface defines a contract that multiple classes can follow.
Example of a Generic Interface
// Generic interface
interface Computable<T> {
T compute(T a, T b);
}
// Implementation for Integer
class IntegerAdder implements Computable<Integer> {
@Override
public Integer compute(Integer a, Integer b) {
return a + b;
}
}
// Implementation for String
class StringConcatenator implements Computable<String> {
@Override
public String compute(String a, String b) {
return a + b;
}
}
public class GenericInterfaceExample {
public static void main(String[] args) {
Computable<Integer> intAdder = new IntegerAdder();
System.out.println("Sum: " + intAdder.compute(5, 10));
Computable<String> strConcat = new StringConcatenator();
System.out.println("Concatenation: " + strConcat.compute("Hello, ", "World!"));
}
}
✅ Output:
Sum: 15
Concatenation: Hello, World!