Open In App

Difference Between BufferedReader and FileReader in Java

Last Updated : 13 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

BufferedReader and FileReader both classes are used to read data from a given character stream. Both of them have some pros and some cons. In this article, we will discuss the differences between them. Though the most important difference is in the way they work, but we will discuss the other details also. 

What is a Buffer?

A buffer is a small portion of the device memory storage used to temporarily store some amount of data. Usually, Buffers use the RAM of the device to store the temporary data, and hence, accessing data from the buffer is much faster than accessing the same amount of data from the hard drive. 

Differences between BufferedReader and FileReader are illustrated over and discussed over major parameters taken into consideration as follows:

  1. Usage
  2. Efficiency
  3. Speed
  4. Reading lines

1. Usage

FileReader is used to read a file from a disk drive whereas BufferedReader is not bound to only reading files. It can be used to read data from any character stream. FileReader class provides two constructors: 

  • FileReader(File file): It takes a File object that represents a file in your disk and creates a new FileReader instance.
  • FileReader(FileDescriptor fd) : Creates a new FileReader, given the FileDescriptor to read from.
  • FileReader(String fileName): Takes the name of the file as the only parameter and creates a new FileReader instance to read the file.

BufferedReader class provides two constructors: 

  • BufferedReader(Reader rd): It uses a Reader to read data from the character input stream and creates a default sized input buffer.
  • BufferedReader(Reader rd, int size): Takes two parameters:
    • First: A Reader that is used to read the input stream data
    • Second: The size of the input buffer. It creates a new BufferedReader with the given sized input buffer.

As seen, BufferedReader accepts any type of Reader(StringReader, FileReader, etc.) and hence capable of reading from any character input stream. Whereas, FileReader is capable of reading characters from files only. Usually, we wrap a FileReader with BufferedReader to read characters from files. 

2. Efficiency

BufferedReader is much more efficient than FileReader in terms of performance. FileReader directly reads the data from the character stream that originates from a file. Each time, it reads a character, it directly accesses the disk drive and every time it takes some time for the disk drive to position the read head correctly which makes it very inefficient.

Whereas BufferedReader creates an input buffer and allows the input to be read from the hard drive in large chunks of data rather than a byte at a time, resulting in a huge improvement in performance. The default buffer size is 8Kb( which is enough in most cases) though it can be customized. BufferedReader reads lots of data at a time and stores it in the created buffer memory. When java.io.BufferedReader#read() is called, it reads the data from the memory buffer. When data is not available in the buffer, it makes a corresponding read request of the underlying character stream and loads lots of data into the created buffer. As a result, we do not have to access the hard drive directly when reading each character, we can read from the buffer memory which is fast and much more efficient.

3. Speed

As BufferedReader uses buffer internally, this class is much faster than FileReader. BufferReader doesn’t need to access the hard drive every time like FileReader and hence faster.

4. Reading Lines

In most cases, you would like to read a line at a time rather than reading a character at a time and only the BufferedReader provides a readLine() method that reads a whole line at a time. Simply, the given Reader(FileReader in this case) reads the characters and stores them in the buffer. When the java.io.BufferedReader#readLine() method is called, characters of a line stored in the buffer, are returned as a String. It saves lots of time and hence is faster than FileReader#read() method. Note that, BufferedReader is able to read a whole line at a time only because it uses a buffer memory, it can store the characters of a line in the buffer and read all the characters together directly from the buffer.

Conclusion: Differences between BufferedReader and FileReader 

   Basis                             BufferedReader                                              FileReader 
Use It is used to read characters from any type of character input stream (String, Files, etc.) It can be used only for reading files
Buffer Uses Buffer internally to read characters from Doesn’t use Buffer. Directly reads from the file by accessing the hard drive.
Speed Faster Slower
Efficiency Much more efficient for reading files Less efficient 
Reading Lines BufferedReader can be used to read a single character at a time as well as a line at a time. It can read only one character at a time, can not read lines

Implementation: 

Example 1: Reading lines using BufferedReader

Java




// Java Program to differentiate between
// BufferedReader and FileReader in Java
 
// Reading lines using BufferedReader
 
// Import necessary classes
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
// Class
public class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        FileReader reader;
 
        // Try block to check exceptions
        try {
 
            // A Reader that reads creates an input
            // character stream
            // and reads characters from it
            reader = new FileReader("geeks.txt");
 
            // Creating a BufferedReader object (instance)
            //  that 16Kb in buffer in the memory
            BufferedReader buffer
                = new BufferedReader(reader, 16384);
 
            // Custom input
            // A string to store the lines
            String line = "";
 
            // Maintaining real time count using
            // currentTimeMillis() method to get time taken
            // to read the data
            long initialTime = System.currentTimeMillis();
            while (true) {
 
                // Try block to check exceptions
                try {
 
                    // readLine() method of BufferedReader
                    // returns
                    //  a whole line at a time
                    line = buffer.readLine();
                }
 
                // Catch block to handle exceptions
                catch (IOException e) {
 
                    // Print the line where exception
                    // occurred
                    e.printStackTrace();
                }
 
                // When the read head reaches the "End Of
                // File" the readLine method returns null
                if (line == null)
                    break;
 
                // Prints the line
                System.out.println(line);
            }
 
            // New line
            System.out.println();
 
            // Display the time taken to read the data
            System.out.println("Time taken : "
                               + (System.currentTimeMillis()
                                  - initialTime));
 
            // Try block to check exceptions
            try {
 
                // Close all the streams
                buffer.close();
                reader.close();
            }
 
            // Catching only exceptions those occurred
            // only during closing streams
            catch (IOException e) {
 
                // Prints the line number where exception
                // occurred
                e.printStackTrace();
            }
        }
 
        // Catch block
        catch (FileNotFoundException e) {
 
            // print the exception only if
            // the file not found
            e.printStackTrace();
        }
    }
}


 
 

Output: From the file ‘geeks.txt’ in the local directory used in the above program

 

Hello geeks!

BufferedReader uses a FileReader to read data from this file.

BufferedReader creates a input buffer with the given size (if no such size given then the default size is 8Kb).

If we use only the FileReader, then it reads one character at a time by directly accessing the disk drive.

Each time it reads the data, it takes some time for the disk drive to position the read head correctly which makes it very inefficient.

Accessing the disk drive every time for reading a single character affects the performance.

Whereas, BufferedReader creates a buffer, and reads large amount of data using the given FileReader and loads it into a input buffer in the memory.

Each time you want to read the file data, you can read it from the buffer( you don’t have to directly access the disk drive every time) and hence is faster than FileReader.  

Time taken : 3

 

Example 2: Reading lines using only the FileReader

 

Java




// Java Program to differentiate between
// BufferedReader and FileReader in Java
 
// Reading lines using FileReader
 
// Import necessary classes
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
// Class
public class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
        FileReader reader;
 
        // Try block to check if exception occurred
        try {
 
            // A FileReader to read data from "geeks.txt"
            // File present in local directory
            reader = new FileReader("geeks.txt");
 
            char ch;
 
            // An integer to store the integer
            // returned by FileReader#read() method
            int i = -1;
 
            // Stores the initial current time
            long initialTime = System.currentTimeMillis();
            while (true) {
                try {
                    // The read() method of FileReader
                    // reads one character at a time
                    // and returns it as an integer
                    i = reader.read();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
 
                // When the "End Of File" is reached
                // the read() method returns -1
                if (i == -1)
                    break;
 
                ch = (char)i;
                System.out.print(ch);
            }
 
            // New line
            System.out.println();
 
            // Display and print the time taken
            System.out.println("Time taken : "
                               + (System.currentTimeMillis()
                                  - initialTime));
 
            try {
                reader.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}


Output: From the file ‘geeks.txt’ in the local directory used in the above program

Hello geeks!

BufferedReader uses a FileReader to read data from this file.

BufferedReader creates a input buffer with the given size (if no such size given then the default size is 8Kb).

If we use only the FileReader, then it reads one character at a time by directly accessing the disk drive.

Each time it reads the data, it takes some time for the disk drive to position the read head correctly which makes it very inefficient.

Accessing the disk drive every time for reading a single character affects the performance.

Whereas, BufferedReader creates a buffer, and reads large amount of data using the given FileReader and loads it into a input buffer in the memory.

Each time you want to read the file data, you can read it from the buffer( you don’t have to directly access the disk drive every time) and hence is much more efficient than FileReader.

  

Time taken : 32

Note:

  1. The time taken for the reading process might vary in your system, but the fact is that BufferedReader works faster and more efficiently than the FileReader.
  2. If you want a good performance, then you would you use both of them together. BufferedReader itself does not read data from an input stream, it uses a Reader(usually a FileReader) that interacts with the native system APIs to read characters from the given input source( A file in case of a FileReader ). The BufferedReader class just adds a buffer to the character stream and reads characters from the buffer, not directly from the input source. So, you can read a file using only the FileReader because it has access to the hard drive to read data from. But you can not use “only BufferedReader” to read a file, as it doesn’t have the access to the hard drive, you have to provide a Reader( a FileReader) that has the access.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads