Tuesday, 30 May 2017

Tutorial 20: Reading Text Files with FileReader



In this tutorial, I will show you the more traditional way of reading files in Java.

As usual, make sure you have a text file somewhere on your computer. Also ensure that it contains some data that we are going to read using Java.

Right-click the text file you have just created and click in Properties. Copy the file location and pass it on to an object of type File like this:

File file = new File (“C/Users/Mukami/Desktop/Document1.txt”);

Add the import for the File class.

Now that we have the file, we are going to read it. To do so, we need a FileReader object and pass on the File object to its constructor.

FileReader fileReader1 = new FileReader (file);

Add the import for the FileReader class.

Now, FileReader will try to open the text file, but if it cannot find the file, it will throw a FileNotFoundException. So in this case, we can handle the exception by surrounding the above line with a try catch block as follows:

try {
            FileReader fileReader1 = new FileReader (file);
            } catch (FileNotFoundException e) {
                        System.out.println(“Could not find the file: ” + file.toString());
}

Now, we want to read the file character by character, which is called buffering. So to do this, we need to use a class called BufferedReader. Here is how we declare buffered reader:

try {
            FileReader fileReader1 = new FileReader (file);
            BufferedReader bufferedReader = new BufferedReader(fileReader1);
            } catch (FileNotFoundException e) {
                        System.out.println(“Could not find the file: ” + file.toString());
}

Add the import for the BufferedReader class.

Now, we can create an object of type String to hold the content read by the object of type BufferedReader.

try {
            FileReader fileReader1 = new FileReader (file);
            BufferedReader bufferedReader = new BufferedReader(fileReader1);
            String content;
            content = bufferedReader.readLine();
            } catch (FileNotFoundException e) {
                        System.out.println(“Could not find the file: ” + file.toString());
}

Now the line content = bufferedReader.nextLine(); throws the unable to read file IOException. To handle this, we surround the try block with a multi catch like this:

try {
            FileReader fileReader1 = new FileReader (file);
            BufferedReader bufferedReader = new BufferedReader(fileReader1);
            String content;
            content = bufferedReader.readLine();
            } catch (FileNotFoundException e) {
                        System.out.println(“Could not find the file: ” + file.toString());
}
catch (IOException e) {
            System.out.println(“Could not read the file: ” + file.toString());
}

Java may not be able to read the file because it may be corrupted or doesn’t have permission to access it. 

Finally, you can output the contents of the file to the console:

try {
            FileReader fileReader1 = new FileReader (file);
            BufferedReader bufferedReader = new BufferedReader(fileReader1);
            String content;
            content = bufferedReader.readLine();
            System.out.println (content);
            } catch (FileNotFoundException e) {
                        System.out.println(“Could not find the file: ” + file.toString());
}
catch (IOException e) {
            System.out.println(“Could not read the file: ” + file.toString());
}

Now, you will notice that when you run the above program, it will only read one line, because BufferedReader only reads one line at a time. So to read the entire file, we have to enclose the content = bufferedReader.nextLine(); and System.out.println(content) in a while loop as shown below. Remember that we want the while loop to stop when the line is equal to null:

try {
            FileReader fileReader1 = new FileReader (file);
            BufferedReader bufferedReader = new BufferedReader(fileReader1);
            String content;
            while ((content = bufferedReader.readLine()) != null) {
            System.out.println (content);
            }
            } catch (FileNotFoundException e) {
                        System.out.println(“Could not find the file: ” + file.toString());
}
catch (IOException e) {
            System.out.println(“Could not read the file: ” + file.toString());
}

The remaining problem is the fact that we have not closed the BufferedReader object and this might create a problem because of the handling of open files. The reason why we need to close BufferedReader is because it will close all the other objects up the line. So this means that we only have to close the last one, which is the BufferedReader object. But where do we close the BufferedReader object? 

We need to close it after all the operations are complete i.e., at the end of the file. However, we initialized the BifferedReader object within the try block, meaning that its scope is only within the curly brackets of the try block. So to get around this, we need to declare the BufferedReader object outside the try block, and only use the reference variable inside the try block like this:

BufferedReader bufferedReader;

try {
            FileReader fileReader1 = new FileReader (file);
            bufferedReader = new BufferedReader(fileReader1);
            String content;
            while ((content = bufferedReader.readLine()) != null) {
            System.out.println (content);
            }
            } catch (FileNotFoundException e) {
                        System.out.println(“Could not find the file: ” + file.toString());
}
catch (IOException e) {
            System.out.println(“Could not read the file: ” + file.toString());
}

br.close();

Now, the br.close(); statement throws an unhandled exception, because if the file couldn’t be opened or read, then br.close(); will never take place. So, we also need to surround br.close(); with a try catch block as shown below:

try {
            FileReader fileReader1 = new FileReader (file);
            bufferedReader = new BufferedReader(fileReader1);
            String content;
            while ((content = bufferedReader.nextLine()) != null) {
            System.out.println (content);
            }
            } catch (FileNotFoundException e) {
                        System.out.println(“Could not find the file: ” + file.toString());
}
catch (IOException e) {
            System.out.println(“Could not read the file: ” + file.toString());
}

try {
bufferedReader.close();
} catch (IOException e) {
            System.out.println(“Could not close file: ” + file.toString());
}

Now, an error will come up and say that bufferedReader doesn’t exist. This is because we never initialized the BufferedReader object outside the first try catch block. So to make the error go away, equate the bufferedReader reference variable to null like this:

BufferedReader bufferedReader = null;

In case the file doesn’t exist, Java will throw a null pointer exception and output a stack trace. This is however not preferred by the users of your software. It would be better if we could handle the null pointer exception by surrounding the last try catch block with another catch block like this:

try {
bufferedReader.close();
} catch (IOException e) {
            System.out.println(“Could not close file: ” + file.toString());
}
Figure 1: Reading files using FileReader.
 


So that is it for reading files using BufferedReader.

In the next tutorial, we will look at a neater way to read files using BufferedReader than the one we have discussed in this tutorial.

In case you have any questions, please post them in the comments section below and I will address them. 

Until next time, take care.

No comments:

Post a Comment