Lesson 3
Reading Files Character-by-Character with FileReader
Introduction to FileReader

Welcome to this lesson on reading files with FileReader in Java. Building upon our foundational knowledge of handling text files, this lesson will guide you through utilizing Java's java.io.FileReader to read files character by character. These methods are crucial for handling varying file sizes efficiently and managing memory use effectively. By the end of this lesson, you'll be able to read entire files, specific portions, and process files in manageable chunks, granting you flexible control over text data processing.

Example File

Before we jump into reading files, let's review the example file that we will work with:

Plain text
1Hi! 2This file contains some sample example text to use to test how the read method works. 3Let's do some programming!

This file contains multiple lines of varied lengths.

Understanding FileReader

The FileReader class in Java is part of the java.io package and is designed for reading files as a stream of characters. It provides methods to open a file and read its contents character by character, which is helpful for detailed text processing. To read a file's entire content character by character, we open the file using FileReader and utilize the read() method, which reads the next character in the stream and returns its integer representation.

Here is how to read a file completely character by character using a loop:

Java
1import java.io.FileReader; 2import java.io.IOException; 3import java.nio.file.Path; 4import java.nio.file.Paths; 5 6public class Main { 7 public static void main(String[] args) throws IOException { 8 // Create a Path object for the specified file 9 Path filePath = Paths.get("example.txt"); 10 11 // Open the file for reading with FileReader 12 FileReader reader = new FileReader(filePath.toFile()); 13 14 // Variable to store the integer representation of the character being read 15 int charInt; 16 17 // Read each character from the file until end-of-file is reached 18 while ((charInt = reader.read()) != -1) { 19 // Cast the integer to a character and output it 20 System.out.print((char) charInt); 21 } 22 23 // Close the FileReader to free system resources 24 reader.close(); 25 } 26}

To open the file, filePath.toFile() converts the Path object into a File object required by FileReader. The read() method reads a character from the file and returns its integer representation, which is then cast back to a character using (char). The loop continues until all characters have been read. It is crucial to close the FileReader after the operations to release system resources and prevent potential file locks.

The expected output is:

Plain text
1Hi! 2This file contains some sample example text to use to test how the read method works. 3Let's do some programming!

This approach suits situations where processing files one character at a time is necessary or preferred. It provides a straightforward way to read entire files while maintaining resource efficiency, making FileReader a versatile option for file manipulation in Java.

Reading Defined Portions of a File

In many situations, you may only need to read a specific number of characters rather than the entire file. This can be accomplished by utilizing read() inside a loop that iterates a set number of times based on the count of characters you'd like to read.

Java
1import java.io.FileReader; 2import java.io.IOException; 3import java.nio.file.Path; 4import java.nio.file.Paths; 5 6public class Main { 7 public static void main(String[] args) throws IOException { 8 // Create a Path object for the specified file 9 Path filePath = Paths.get("example.txt"); 10 11 // Open the file for reading with FileReader 12 FileReader reader = new FileReader(filePath.toFile()); 13 14 // Number of characters to read 15 int charactersToRead = 10; 16 17 // Variable to store the integer representation of the character being read 18 int charInt; 19 20 // Read characters from the file until the specified number is reached or end-of-file 21 while ((charInt = reader.read()) != -1 && charactersToRead > 0) { 22 // Cast the integer to a character and output it 23 System.out.print((char) charInt); 24 // Decrement the charactersToRead count 25 charactersToRead--; 26 } 27 28 // Close the FileReader to free system resources 29 reader.close(); 30 } 31}

The loop continues until the specified number of characters (in this case, 10) is read or until the end of the file is reached, whichever comes first.

The expected output is:

Plain text
1Hi! 2This

This method is especially useful for preliminary processing or debugging large files.

Sequential File Reading

Sequential reading in file handling refers to the process of reading a file's contents in a predefined, orderly manner — part by part — without restarting from the beginning each time. For instance, by using loops in combination with the read() method, each subsequent read operation continues from where the last one concluded. This approach is particularly beneficial when dealing with large files or when you require distinct segments from a file.

Here's an example:

Java
1import java.io.FileReader; 2import java.io.IOException; 3import java.nio.file.Path; 4import java.nio.file.Paths; 5 6public class Main { 7 public static void main(String[] args) throws IOException { 8 // Create a Path object for the specified file 9 Path filePath = Paths.get("example.txt"); 10 // Open the file for reading with FileReader 11 FileReader reader = new FileReader(filePath.toFile()); 12 // Variable to store the integer representation of the character being read 13 int charInt; 14 15 // First segment: read the initial 10 characters 16 int firstReadLength = 10; 17 // Read the first 10 characters from the file 18 System.out.println("First 10 characters:"); 19 while ((charInt = reader.read()) != -1 && firstReadLength > 0) { 20 // Cast the integer to a character and output it 21 System.out.print((char) charInt); 22 // Decrement the firstReadLength count 23 firstReadLength--; 24 } 25 26 // Second segment: read the next 10 characters 27 int nextReadLength = 10; 28 // Read the next set of 10 characters from the file 29 System.out.println("\n\nNext 10 characters:"); 30 while ((charInt = reader.read()) != -1 && nextReadLength > 0) { 31 // Cast the integer to a character and output it 32 System.out.print((char) charInt); 33 // Decrement the nextReadLength count 34 nextReadLength--; 35 } 36 37 // Close the FileReader to free system resources 38 reader.close(); 39 } 40}

This program reads and prints the first 10 characters from the file, then moves forward to read the next set of 10 characters. The FileReader maintains its position within the file, allowing seamless sequential access to subsequent portions.

Expected output would be:

Plain text
1First 10 characters: 2Hi! 3This f 4 5Next 10 characters: 6ile contai

This technique is advantageous when you only need specific sections of a file or when you want to process large files in smaller chunks, thereby reducing memory consumption and improving performance. It facilitates better data manipulation in scenarios where progressive reading is required.

Summary and Next Steps

In this lesson, you learned how to effectively use the Java FileReader class for various file reading tasks. We covered reading entire files, specific portions, and processing large files efficiently by chunk reading. These techniques provide you with control and flexibility in handling text data.

Experiment with these methods using different files to strengthen your understanding of file manipulation in Java. Keep practicing to enhance your skills in file handling and data processing. You have made substantial progress in mastering file manipulation in Java.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.