File I/O
Dashboard
Topic 21/30

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.

FileBasicsDemo.javaJava
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.

BufferedReadWriteDemo.javaJava
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(); }
    }
}
FileCopy.javaJava
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.

SerializationDemo.javaJava
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.

NIOFilesDemo.javaJava
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();
        }
    }
}
Tip: The Files.readString() and Files.writeString() methods introduced in Java 11 make simple text file I/O a one-liner.