Java provides a robust set of classes and interfaces for Input/Output (I/O) operations, commonly referred to as File Handling. These classes are part of the java.io
package and allow you to read from and write to files, streams, and other data sources. Java I/O is divided into two main types:
- Byte Streams: For handling binary data (e.g., images, videos).
- Character Streams: For handling text data.
1. Byte Streams
Byte streams are used to read and write binary data. The core classes for byte streams are:
- InputStream: Abstract class for reading bytes.
- OutputStream: Abstract class for writing bytes.
Common Byte Stream Classes
- FileInputStream: Reads bytes from a file.
- FileOutputStream: Writes bytes to a file.
- BufferedInputStream: Adds buffering to an input stream.
- BufferedOutputStream: Adds buffering to an output stream.
Example: Reading and Writing Bytes
import java.io.*;
public class ByteStreamExample {
public static void main(String[] args) {
String filePath = "example.txt";
// Writing bytes to a file
try (FileOutputStream fos = new FileOutputStream(filePath)) {
String text = "Hello, Byte Stream!";
fos.write(text.getBytes()); // Convert string to bytes and write
System.out.println("Data written to file.");
} catch (IOException e) {
e.printStackTrace();
}
// Reading bytes from a file
try (FileInputStream fis = new FileInputStream(filePath)) {
int data;
while ((data = fis.read()) != -1) { // Read byte by byte
System.out.print((char) data); // Convert byte to char
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. Character Streams
Character streams are used to read and write text data. The core classes for character streams are:
- Reader: Abstract class for reading characters.
- Writer: Abstract class for writing characters.
Common Character Stream Classes
- FileReader: Reads characters from a file.
- FileWriter: Writes characters to a file.
- BufferedReader: Adds buffering to a reader.
- BufferedWriter: Adds buffering to a writer.
Example: Reading and Writing Characters
import java.io.*;
public class CharacterStreamExample {
public static void main(String[] args) {
String filePath = "example.txt";
// Writing characters to a file
try (FileWriter fw = new FileWriter(filePath)) {
fw.write("Hello, Character Stream!");
System.out.println("Data written to file.");
} catch (IOException e) {
e.printStackTrace();
}
// Reading characters from a file
try (FileReader fr = new FileReader(filePath)) {
int data;
while ((data = fr.read()) != -1) { // Read character by character
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. Buffered Streams
Buffered streams improve I/O performance by reducing the number of reads/writes to the underlying stream.
Example: Using Buffered Streams
import java.io.*;
public class BufferedStreamExample {
public static void main(String[] args) {
String filePath = "example.txt";
// Writing to a file using BufferedWriter
try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) {
bw.write("Hello, Buffered Stream!");
System.out.println("Data written to file.");
} catch (IOException e) {
e.printStackTrace();
}
// Reading from a file using BufferedReader
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) { // Read line by line
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. File Class
The File
class in Java represents a file or directory path. It provides methods for file manipulation, such as creating, deleting, and checking file properties.
Example: File Operations
import java.io.File;
public class FileExample {
public static void main(String[] args) {
String filePath = "example.txt";
// Create a File object
File file = new File(filePath);
// Check if the file exists
if (file.exists()) {
System.out.println("File exists.");
} else {
System.out.println("File does not exist.");
}
// Create a new file
try {
if (file.createNewFile()) {
System.out.println("File created.");
} else {
System.out.println("File already exists.");
}
} catch (IOException e) {
e.printStackTrace();
}
// Delete the file
if (file.delete()) {
System.out.println("File deleted.");
} else {
System.out.println("Failed to delete the file.");
}
}
}
5. Serialization and Deserialization
Java I/O also supports serialization (converting objects to bytes) and deserialization (converting bytes back to objects). This is useful for saving object states to files or sending objects over a network.
Example: Serialization and Deserialization
import java.io.*;
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
public class SerializationExample {
public static void main(String[] args) {
String filePath = "person.ser";
// Serialization
try (FileOutputStream fos = new FileOutputStream(filePath);
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
Person person = new Person("Alice", 30);
oos.writeObject(person);
System.out.println("Object serialized.");
} catch (IOException e) {
e.printStackTrace();
}
// Deserialization
try (FileInputStream fis = new FileInputStream(filePath);
ObjectInputStream ois = new ObjectInputStream(fis)) {
Person person = (Person) ois.readObject();
System.out.println("Object deserialized: " + person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
6. Random Access Files
The RandomAccessFile
class allows reading from and writing to a file at specific positions.
Example: Random Access File
import java.io.*;
public class RandomAccessFileExample {
public static void main(String[] args) {
String filePath = "example.txt";
try (RandomAccessFile raf = new RandomAccessFile(filePath, "rw")) {
// Write data
raf.writeBytes("Hello, Random Access File!");
// Move to a specific position
raf.seek(7);
// Read data from the current position
byte[] buffer = new byte[10];
raf.read(buffer);
System.out.println("Data: " + new String(buffer));
} catch (IOException e) {
e.printStackTrace();
}
}
}
7. Key Points to Remember
- Use byte streams for binary data and character streams for text data.
- Use buffered streams to improve I/O performance.
- The
File
class is used for file and directory manipulation. - Serialization and deserialization are used to save and restore object states.
RandomAccessFile
allows reading and writing at specific positions in a file.
8. Example: Combining File Handling Techniques
import java.io.*;
public class FileHandlingExample {
public static void main(String[] args) {
String filePath = "example.txt";
// Write to file using BufferedWriter
try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) {
bw.write("Hello, File Handling!");
System.out.println("Data written to file.");
} catch (IOException e) {
e.printStackTrace();
}
// Read from file using BufferedReader
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println("Data read from file: " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Check file properties using File class
File file = new File(filePath);
System.out.println("File exists: " + file.exists());
System.out.println("File size: " + file.length() + " bytes");
}
}
By mastering Java I/O and file handling, you can efficiently manage file operations and data processing in your applications!