bufferedreader和filereader之间的具体区别

时间:2012-03-10 17:58:12

标签: java bufferedreader filereader

我想知道BufferedReaderFileReader之间的具体差异。

我知道BufferedReaderFileReader相比效率更高,但有人可以解释原因(具体而详细)吗?感谢。

6 个答案:

答案 0 :(得分:98)

首先,您应该了解"流媒体"在Java中因为所有"读者"在Java中建立在这个概念上。

文件流

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

// 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位,你会看到屏幕上印有奇怪的字符或写在输出文件中(如果字符长度超过1个字节)。

文件阅读

这只是一种说法"文件流"包含charset支持(即不需要像之前一样定义charset)。

FileReader 类专门用于处理文本文件。 正如您之前所见,Streaming文件最适合处理原始二进制数据,但出于文本原因,效率并不高。

所以Java-dudes添加了 FileReader 类,专门处理文本文件。它一次读取2个字节(或4个字节,取决于字符集)。与前面的 FileInputStream !!

相比,有了相当大的改进

所以流媒体操作就像这样,

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

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

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

但同样它仍然太慢(成像一次读取2个字节并循环通过它!)。

缓冲流

解决在一个字节或2上连续循环的问题.Java-dudes增加了另一个壮观的功能。 "在处理之前创建数据缓冲区。"

当用户在YouTube上流式传输视频时,这个概念非常相似。视频在播放前进行缓冲,以提供完美的视频观看体验。 (因此,浏览器会保持缓冲,直到整个视频提前缓冲。) BufferedReader 类使用相同的技术。

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

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

当"读"指令被赋予 BufferedReader 对象,它使用 FileReader 对象从文件中读取数据。当给出指令时, FileReader 对象一次读取2(或4)个字节,并将数据返回到 BufferedReader ,读者会一直这样做,直到它到达& #39; \ n'或者' \ r \ n' (行符号的结尾)。 一旦线被缓冲,读者就会耐心等待,直到给出缓冲下一行的指令。

同时, BufferReader 对象创建一个特殊的内存位置(在RAM上),称为" Buffer",并存储来自 FileReader的所有提取的数据 object。

// 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 作为对象,它会缓冲终端/控制台输入数据直到它击中一个新的线符号。比如,

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

这样,您可以使用相同的 BufferReader 类读取(或缓冲)多个流,例如文本文件,控制台,打印机,网络数据等,您必须记住的是,< / p>

 bufferedReader.readLine();

打印您已缓冲的内容。

答案 1 :(得分:75)

以简单的方式:

FileReader类是从文件中读取字符的通用工具。 BufferedReader类可以包含读取器,如FileReader,以缓冲输入并提高效率。因此,您不会使用其中一个,而是同时将FileReader对象传递给BufferedReader构造函数。

非常详细

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

enter image description here

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

BufferedReader stdin =
    new BufferedReader(new InputStreamReader( System.in ));

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

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

答案 2 :(得分:0)

BufferedReader需要一个Reader,其中FileReader是一个 - 它来自InputStreamReader,它来自Reader。

答案 3 :(得分:-1)

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这样的读者。

答案 4 :(得分:-1)

FileReader类有助于写入文件,但效率很低,因为它一次从文件中检索一个字符,但BufferedReader获取数据块并将其存储在缓冲区中,而不是从文件后退中恢复一个字符容易使用缓冲区。

答案 5 :(得分:-2)

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

FileReader - 顾名思义。