Reading a File in Java: A Comprehensive Tutorial with Code Examples

In Java, reading a file is a common task that involves retrieving data from a file and processing it. Java provides several ways to read files, each suited for different use cases.

Whether you are reading character data, binary data, or lines from a file, Java offers classes like FileReader, BufferedReader, Scanner, and the modern Files class from the NIO package.

This tutorial will guide you through various methods to read files in Java, providing examples for each approach.

Table of Contents:

1. Introduction to File Reading in Java

Java provides multiple classes and methods for reading data from files:

FileReader: Reads character files.
BufferedReader: Buffers characters for efficient reading of large files.
Scanner: Reads file data using simple parsing capabilities.
Files: A modern utility class for reading files (introduced in Java 7).
InputStream: Reads binary data from files.
Each of these classes serves different purposes, depending on the size of the file, the type of data being read, and the performance needs of the application.

2. Reading a File Using FileReader

The FileReader class is a basic way to read character data from a file. It reads one character at a time, making it suitable for small files.

Example 1: Reading a File Using FileReader

import java.io.FileReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        try {
            // Create a FileReader object
            FileReader reader = new FileReader("example.txt");

            int character;

            // Read each character until the end of the file
            while ((character = reader.read()) != -1) {
                System.out.print((char) character);  // Cast int to char
            }

            reader.close();  // Close the FileReader
        } catch (IOException e) {
            System.out.println("An error occurred while reading the file.");
            e.printStackTrace();
        }
    }
}

Explanation:

FileReader reads one character at a time. The read() method returns the character as an int (which is cast to char).
Always close the FileReader after use to release resources.

3. Reading a File Line by Line Using BufferedReader

BufferedReader provides efficient reading of large files by buffering input. It can also read files line by line, making it a better choice for larger files or when you need to process data line by line.

Example 2: Reading a File Line by Line Using BufferedReader

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        try {
            // Create a BufferedReader object
            BufferedReader reader = new BufferedReader(new FileReader("example.txt"));

            String line;

            // Read each line until the end of the file
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            reader.close();  // Close the BufferedReader
        } catch (IOException e) {
            System.out.println("An error occurred while reading the file.");
            e.printStackTrace();
        }
    }
}

Explanation:

BufferedReader is wrapped around FileReader to provide buffering.
The readLine() method reads the file line by line and returns null when the end of the file is reached.
Always close the BufferedReader after reading the file.

4. Reading a File Using Scanner

The Scanner class provides a flexible way to read files. It can parse input based on different data types (e.g., int, double, String) and delimiters.

Example 3: Reading a File Using Scanner

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        try {
            // Create a Scanner object to read the file
            Scanner scanner = new Scanner(new File("example.txt"));

            // Read and print each line
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                System.out.println(line);
            }

            scanner.close();  // Close the Scanner
        } catch (FileNotFoundException e) {
            System.out.println("File not found.");
            e.printStackTrace();
        }
    }
}

Explanation:

Scanner is a simple class that can read files and parse input with ease.
hasNextLine() checks if there is another line to read, and nextLine() reads and returns that line.
Scanner is a good choice when you need to parse formatted data from a file.

5. Reading a File Using Files (Java NIO)

The Files class from the Java NIO package offers modern methods for reading files. It allows reading all lines or all bytes of a file at once.

Example 4: Reading a File Using Files.readAllLines()

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        try {
            // Create a Path object
            Path filePath = Paths.get("example.txt");

            // Read all lines from the file
            List lines = Files.readAllLines(filePath);

            // Print each line
            for (String line : lines) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("An error occurred while reading the file.");
            e.printStackTrace();
        }
    }
}

Explanation:

Files.readAllLines() reads all lines from the file and returns them as a List.
This method is suitable for smaller files, as it loads the entire file into memory.

6. Reading a File as Bytes

If you need to read a file as binary data (for example, an image or a binary file), you can use the Files.readAllBytes() method, which reads the entire file into a byte array.

Example 5: Reading a File as Bytes Using Files.readAllBytes()

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {
    public static void main(String[] args) {
        try {
            // Create a Path object
            Path filePath = Paths.get("binaryfile.bin");

            // Read all bytes from the file
            byte[] fileBytes = Files.readAllBytes(filePath);

            // Print the byte array length
            System.out.println("File size in bytes: " + fileBytes.length);
        } catch (IOException e) {
            System.out.println("An error occurred while reading the file.");
            e.printStackTrace();
        }
    }
}

Explanation:

Files.readAllBytes() reads the entire file into a byte array.
This method is used for reading binary files such as images, PDFs, or other non-text data.

7. Handling Exceptions When Reading Files

File reading operations in Java can throw exceptions like IOException or FileNotFoundException. These exceptions must be handled using try-catch blocks or declared using the throws keyword.

Example 6: Handling FileNotFoundException and IOException

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        try {
            // Example of reading using Scanner
            Scanner scanner = new Scanner(new File("example.txt"));
            while (scanner.hasNextLine()) {
                System.out.println(scanner.nextLine());
            }
            scanner.close();

            // Example of reading using Files
            Path filePath = Paths.get("example.txt");
            byte[] fileBytes = Files.readAllBytes(filePath);
            System.out.println("Read " + fileBytes.length + " bytes from the file.");
        } catch (FileNotFoundException e) {
            System.out.println("The specified file was not found.");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("An I/O error occurred.");
            e.printStackTrace();
        }
    }
}

Explanation:

File reading operations can fail due to issues like file not found or I/O errors. Always handle these exceptions to prevent crashes and provide user-friendly error messages.

8. Best Practices for Reading Files in Java

Always close resources: Always close file reading resources like BufferedReader or Scanner to prevent memory leaks. Use try-with-resources when possible.

Handle exceptions: Use proper exception handling (IOException, FileNotFoundException) to manage errors during file reading.

Use BufferedReader for large files: For large files, use BufferedReader for efficient line-by-line reading instead of loading the entire file into memory.

Use Files for modern file handling: The Files class from Java NIO offers a modern, cleaner, and more efficient way to read files.

9. Common Use Cases for Reading Files

Example 7: Reading and Processing CSV Files

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        String filePath = "data.csv";

        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;

            while ((line = reader.readLine()) != null) {
                String[] data = line.split(",");  // Split by comma
                System.out.println("Name: " + data[0] + ", Age: " + data[1]);
            }
        } catch (IOException e) {
            System.out.println("An error occurred while reading the file.");
            e.printStackTrace();
        }
    }
}

Explanation:

This example reads a CSV file and processes each line by splitting the data on commas.
You can use this method for processing structured data files such as CSV or tab-delimited files.

Conclusion

Java provides multiple ways to read files, each suited to different use cases.

Whether you're reading small character files with FileReader, large files with BufferedReader, or binary files with Files.readAllBytes(), Java has robust file handling capabilities.

Using the right method, handling exceptions, and following best practices ensures that your file reading operations are efficient, reliable, and easy to manage.

Related posts

Java FileReader Class tutorial with Examples

Java FileWriter Class Tutorial with Examples

Java Directory Management Tutorial with Examples