关于Java:BufferedReader和FileReader之间的特殊区别

Specific difference between bufferedreader and filereader

我想知道BufferedReaderFileReader之间的具体区别。

我确实知道BufferedReader的效率要比FileReader高得多,但是有人可以(具体且详细地)解释原因吗? 谢谢。


首先,您应该了解Java中的"流",因为Java中的所有"阅读器"都是基于此概念构建的。

好。

文件流

好。

文件流由Java中的FileInputStream对象执行。

好。

1
2
3
4
5
// it reads a byte at a time and stores into the 'byt' variable
int byt;
while((byt = fileInputStream.read()) != -1) {
    fileOutputStream.write(byt);
}

该对象实际上一次读取一个字节(8位)并将其写入给定文件。

好。

它的一个实际有用的应用是处理原始的二进制/数据文件,例如图像或音频文件(对于音频文件,使用AudioInputStream而不是FileInputStream)。
另一方面,对于文本文件,这是非常不便且较慢的,因为一次循环遍历一个字节,然后进行一些处理并将处理后的字节存储回去既繁琐又费时。

好。

您还需要提供文本文件的字符集,即,如果字符是拉丁语或中文,等等。否则,该程序将一次解码和编码8位,并且您会看到打印在页面上的奇怪字符。屏幕或写入输出文件中(如果一个char的长度超过1个字节)。

好。

文件读取

好。

这只是表达"文件流式传输"的一种奇特的方式,其中包含了字符集支持(即,无需像以前那样定义字符集)。

好。

FileReader类专门用于处理文本文件。
如您先前所见,流式处理文件最好是处理原始二进制数据,但是出于文本的考虑,它并不是那么有效。

好。

因此,Java-dudes添加了FileReader类,专门处理文本文件。它一次读取2个字节(或4个字节,取决于字符集)。与之前的FileInputStream相比,有了巨大的改进!

好。

这样的流操作就是这样,

好。

1
2
int c;
while ( (c = fileReader.read()) != -1) { // some logic }

请注意,这两个类都使用整数变量来存储从输入文件中检索到的值(因此,在提取时,每个char都将转换为整数,而在存储时会转换回char)。

好。

唯一的好处是,由于此类处理文本文件,因此您不必指定文本文件的字符集和其他一些属性。对于大多数文本文件处理案例,它基本上提供了一种开箱即用的解决方案。它还支持国际化和本地化。

好。

但是同样,它仍然太慢(想象一次读取2个字节并循环遍历!)。

好。

缓冲流

好。

为了解决连续循环一个字节或2个字节的问题。Javadudes添加了另一个引人注目的功能。"在处理之前创建数据缓冲区。"

好。

当用户在YouTube上流式传输视频时,该概念几乎相同。在播放之前先对视频进行缓冲,以提供完美的视频观看体验。 (这样,浏览器会一直保持缓冲状态,直到提前缓冲整个视频为止。)BufferedReader类使用了相同的技术。

好。

BufferedReader对象将FileReader对象作为输入,其中包含有关需要读取的文本文件的所有必要信息。 (例如文件路径和字符集。)

好。

1
BufferedReader br = new BufferedReader( new FileReader("example.txt") );

将" read"指令提供给BufferedReader对象时,它使用FileReader对象从文件中读取数据。给出指令后,FileReader对象一次读取2(或4)个字节,并将数据返回给BufferedReader,并且读取器一直这样做,直到命中' n'或' r n'(线符号)。
一旦缓冲了一行,阅读器就会耐心等待,直到给出缓冲下一行的指令为止。

好。

同时,BufferReader对象在RAM上创建一个特殊的存储位置,称为" Buffer",并存储从FileReader对象获取的所有数据。

好。

1
2
3
4
5
6
7
// this variable points to the buffered line
String line;

// Keep buffering the lines and print it.
while ((line = br.readLine()) != null) {
    printWriter.println(line);
}

现在,在这里,不再需要一次读取2个字节,而是提取整行并将其存储在RAM中的某个位置,当处理完数据后,您可以将整行存储回硬盘。因此,它使进程的运行速度比一次执行2个字节快。

好。

但是同样,为什么我们需要将FileReader对象传递给BufferReader?我们不能只说"缓冲此文件",BufferReader会处理其余的吗?那不是很甜蜜吗?

好。

好吧,以一种仅知道如何创建缓冲区和存储传入数据的方式创建BufferReader类。否定对象来自数据的来源无关紧要。

好。

可以这么说,当您提供FileReader对象作为输入时,它会缓冲文件,就像您将InputStreamReader提供给对象一样,它也会缓冲Terminal / Console输入数据,直到遇到新的行符号。如,

好。

1
2
3
4
// Object that reads console inputs
InputStreamReader console = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(console);
System.out.println(br.readLine());

这样,您可以读取(或缓冲)具有相同BufferReader类的多个流,例如文本文件,控制台,打印机,网络数据等,而您所需要记住的是,

好。

1
 bufferedReader.readLine();

打印您缓冲的所有内容。

好。

好。


以简单的方式:

FileReader类是从File读取字符的通用工具。 BufferedReader类可以包装Readers,例如FileReader,以缓冲输入并提高效率。因此,您不会在一个之上使用另一个,而是通过将FileReader对象传递给BufferedReader构造函数来同时使用两者。

非常详细

FileReader用于从磁盘文件输入字符数据。输入文件可以是普通ASCII,每个字符文本文件一个字节。 Reader流自动将字符从磁盘文件格式转换为内部char格式。输入文件中的字符可能来自UTF格式支持的其他字母,在这种情况下,每个字符最多三个字节。在这种情况下,文件中的字符也将转换为char格式。

enter image description here

与输出一样,优良作法是使用缓冲区提高效率。为此使用BufferedReader。这是我们用于键盘输入的同一类。这些行应该看起来很熟悉:

1
2

这些行创建了BufferedReader,但将其连接到键盘的输入流,而不是文件。

来源:http://www.oopweb.com/Java/Documents/JavaNotes/Volume/chap84/ch84_3.html


BufferedReader需要一个Reader,其中的FileReader是其中之一-它从InputStreamReader继承而来,InputStreamReader从Reader继承而来。


FileReader类有助于写入文件,但是其效率较低,因为它一次只能从文件中检索一个字符,但是BufferedReader会获取大块数据并将其存储在缓冲区中,因此使用缓冲区来代替从文件中一次检索一个字符变得容易。


FileReader-读取字符文件

BufferedReader-"从字符输入流中读取文本,缓冲字符,以便有效读取字符,数组和行。"

http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html

http://docs.oracle.com/javase/7/docs/api/java/io/FileReader.html

实际上,BufferedReader会使用FileReader之类的Reader。


Bufferedreader-您实际上可以代替Scanner方法使用的方法,获取文件,获取输入。

FileReader-顾名思义。