File Handling in Java
File Input/Output (I/O) is essential for reading from and writing to files. Java provides multiple packages for file handling, primarily java.io (older, stream-based) and java.nio.file (newer, path-based).
The File Class
The File class represents file and directory pathnames. It's used for file metadata operations like create, delete, and checking existence.
import java.io.File; import java.io.IOException; public class FileBasicsDemo { public static void main(String[] args) { try { File myObj = new File("testfile.txt"); if (myObj.createNewFile()) { System.out.println("File created: " + myObj.getName()); } else { System.out.println("File already exists."); } System.out.println("Absolute path: " + myObj.getAbsolutePath()); // myObj.delete(); // To delete the file } catch (IOException e) { System.out.println("An error occurred."); e.printStackTrace(); } } }
Byte vs Character Streams
- Byte Streams (InputStream/OutputStream): Used for handling 8-bit bytes (e.g., image, audio, video data). Examples:
FileInputStream,FileOutputStream. - Character Streams (Reader/Writer): Used for handling 16-bit unicode characters (text files). Examples:
FileReader,FileWriter.
Using BufferedReader and BufferedWriter over character streams provides better performance due to buffering.
import java.io.*; public class BufferedReadWriteDemo { public static void main(String[] args) { String filePath = "output.txt"; // Writing using try-with-resources (auto-closes) try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) { bw.write("Hello, World!\n"); bw.write("Java File I/O is great."); } catch (IOException e) { e.printStackTrace(); } // Reading try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }
import java.io.*; public class FileCopy { public static void main(String[] args) { // Byte stream copy example try (FileInputStream in = new FileInputStream("source.bin"); FileOutputStream out = new FileOutputStream("dest.bin")) { int b; while ((b = in.read()) != -1) { out.write(b); } } catch (IOException e) { System.out.println("Error: File missing or access denied."); } } }
Serialization
Serialization is the mechanism of converting the state of an object into a byte stream. Deserialization is the reverse process. A class must implement the Serializable interface to be serializable.
import java.io.*; class Student implements Serializable { private static final long serialVersionUID = 1L; String name; transient int age; // transient fields are not serialized public Student(String n, int a) { name = n; age = a; } } public class SerializationDemo { public static void main(String[] args) throws Exception { Student s1 = new Student("John Doe", 20); // Serialize try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("student.ser"))) { out.writeObject(s1); } // Deserialize try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("student.ser"))) { Student s2 = (Student) in.readObject(); System.out.println("Deserialized Name: " + s2.name + ", Age: " + s2.age); // Output: Name: John Doe, Age: 0 (since age is transient) } } }
Java NIO (New I/O)
The java.nio.file package (NIO.2) introduced in Java 7 provides a more flexible, scalable, and intuitive API for file operations using Path and Files classes.
import java.nio.file.*; import java.util.List; import java.io.IOException; public class NIOFilesDemo { public static void main(String[] args) { Path path = Paths.get("nio_example.txt"); String content = "Using NIO Files class is easy!"; try { // Write to file Files.writeString(path, content, StandardOpenOption.CREATE); // Read all lines List<String> lines = Files.readAllLines(path); for (String line : lines) { System.out.println(line); } // Delete Files.deleteIfExists(path); } catch (IOException e) { e.printStackTrace(); } } }
Files.readString() and Files.writeString() methods introduced in Java 11 make simple text file I/O a one-liner.