📜  JavaBufferedReader和FileReader的区别

📅  最后修改于: 2021-09-14 01:30:05             🧑  作者: Mango

BufferedReader 和 FileReader 这两个类都用于从给定的字符流中读取数据。它们都有一些优点和一些缺点。在本文中,我们将讨论它们之间的区别。虽然最重要的区别在于它们的工作方式,但我们也会讨论其他细节。

什么是缓冲区?

缓冲区是设备内存存储的一小部分,用于临时存储一定数量的数据。通常,缓冲区使用设备的 RAM 来存储临时数据,因此从缓冲区访问数据比从硬盘驱动器访问相同数量的数据要快得多。

BufferedReader 和 FileReader 之间的差异在以下考虑的主要参数上进行了说明和讨论:

  1. 用法
  2. 效率
  3. 速度
  4. 阅读线

1. 用法

FileReader 用于从磁盘驱动器读取文件,而 BufferedReader 不仅限于读取文件。它可用于从任何字符流中读取数据。 FileReader 类提供了两个构造函数:

  • FileReader(File file):它接受一个代表磁盘中文件的 File 对象并创建一个新的 FileReader 实例。
  • FileReader(FileDescriptor fd) :创建一个新的 FileReader,给定要从中读取的 FileDescriptor。
  • FileReader(String fileName):以文件名作为唯一参数,并创建一个新的 FileReader 实例来读取文件。

BufferedReader 类提供了两个构造函数:

  • BufferedReader(Reader rd):它使用 Reader 从字符输入流中读取数据并创建默认大小的输入缓冲区。
  • BufferedReader(Reader rd, int size):采用两个参数:
    • 第一:用于读取输入流数据的Reader
    • 第二:输入缓冲区的大小。它使用给定大小的输入缓冲区创建一个新的 BufferedReader。

正如所见,BufferedReader 接受任何类型的 Reader(StringReader、FileReader 等),因此能够从任何字符输入流中读取。而 FileReader 只能从文件中读取字符。通常,我们用 BufferedReader 包装 FileReader 以从文件中读取字符。

2. 效率

BufferedReader 在性能方面比 FileReader 高效得多。 FileReader 直接从源自文件的字符流中读取数据。每次读取一个字符,它直接访问磁盘驱动器,并且每次磁盘驱动器正确定位读头都需要一些时间,这使得它非常低效。

而 BufferedReader 创建了一个输入缓冲区,并允许以大块数据而不是一次一个字节的形式从硬盘驱动器读取输入,从而大大提高了性能。默认缓冲区大小为 8Kb(在大多数情况下已经足够了),但可以自定义。 BufferedReader 一次读取大量数据并将其存储在创建的缓冲存储器中。当Java.io.BufferedReader#read() 被调用时,它从内存缓冲区读取数据。当缓冲区中没有数据时,它会发出相应的底层字符流读取请求,并将大量数据加载到创建的缓冲区中。因此,我们在读取每个字符时不必直接访问硬盘驱动器,我们可以从缓存中读取,速度更快,效率更高。

3.速度

由于 BufferedReader 在内部使用缓冲区,因此该类比 FileReader 快得多。 BufferReader 不需要像 FileReader 那样每次都访问硬盘驱动器,因此速度更快。

4. 阅读线

在大多数情况下,您希望一次读取一行而不是一次读取一个字符,只有 BufferedReader 提供了一次读取整行的readLine()方法。简单地说,给定的 Reader(在本例中为 FileReader)读取字符并将它们存储在缓冲区中。当调用Java.io.BufferedReader#readLine() 方法时,存储在缓冲区中的行的字符将作为字符串返回。它节省了大量时间,因此比 FileReader#read() 方法更快。需要注意的是,BufferedReader 之所以能够一次读取整行只是因为它使用了缓冲存储器,它可以将一行的字符存储在缓冲区中,并且可以直接从缓冲区中读取所有字符。

结论: BufferedReader 和 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

执行:

示例 1:使用 BuffereReader 读取行

Java
// Java Program to differenciate 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();
        }
    }
}


Java
// Java Program to differenciate 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 occured
        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();
        }
    }
}


输出:来自上述程序中使用的本地目录中的文件“geeks.txt”

示例 2:仅使用 FileReader 读取行

Java

// Java Program to differenciate 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 occured
        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();
        }
    }
}

输出:来自上述程序中使用的本地目录中的文件“geeks.txt”

笔记:

  1. 读取过程所需的时间可能因您的系统而异,但事实是 BufferedReader 比 FileReader 工作得更快、更有效。
  2. 如果你想要一个好的性能,那么你会同时使用它们。 BufferedReader 本身不从输入流中读取数据,它使用与本机系统 API 交互的 Reader(通常是 FileReader)从给定的输入源( FileReader 中的文件)读取字符。 BufferedReader 类只是向字符流添加一个缓冲区并从缓冲区读取字符,而不是直接从输入源读取。因此,您可以仅使用 FileReader 读取文件,因为它可以访问硬盘驱动器以从中读取数据。但是你不能使用“only BufferedReader”来读取文件,因为它没有访问硬盘的权限,你必须提供一个有访问权限的Reader(a FileReader)。