bufferedreader和filereader之间的具体区别

Out*_*ier 51 java filereader bufferedreader

我想知道BufferedReader和之间的具体区别FileReader.

我知道这样做BufferedReader效率要高得多FileReader,但是有人可以解释一下原因(具体而且详细)吗?谢谢.

Meh*_*ara 105

首先,你应该理解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);
} 
Run Code Online (Sandbox Code Playgroud)

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

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

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

文件阅读

这只是说"文件流"的一种奇特方式,它具有包容性的字符集支持(即不需要像之前的那样定义字符集).

的FileReader类是专门用来处理文本文件.正如您之前所见,Streaming文件最适合处理原始二进制数据,但为了文本,它并不那么有效.

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

所以流媒体操作是这样的,

int c;
while ( (c = fileReader.read()) != -1) { // some logic }
Run Code Online (Sandbox Code Playgroud)

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

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

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

缓冲流

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

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

BufferedReader类对象用的FileReader对象作为它包含了所有关于需要读取文本文件中的必要信息的输入.(例如文件路径和字符集.)

BufferedReader br = new BufferedReader( new FileReader("example.txt") );
Run Code Online (Sandbox Code Playgroud)

当给BufferedReader对象发出"read"指令时,它使用FileReader对象从文件中读取数据.当给出一条指令时,FileReader对象一次读取2(或4)个字节,并将数据返回给BufferedReader,读者会一直这样做,直到它命中'\n'或'\ r \n'(结束时)线符号).一旦线路被缓冲,读取器就会耐心等待,直到给出缓冲下一行的指令.

同时,BufferReader对象创建一个特殊的内存位置(在RAM上),称为"缓冲区",并存储来自FileReader对象的所有读取数据.

// this variable points to the buffered line
String line;

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

现在,不是一次读取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());
Run Code Online (Sandbox Code Playgroud)

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

 bufferedReader.readLine();
Run Code Online (Sandbox Code Playgroud)

打印你所缓冲的任何内容.

  • 很棒的解释! (10认同)
  • 谢谢!我只是想解释一些复杂的概念!:) (2认同)

Mr.*_*ack 78

以简单的方式:

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

很详细

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

在此输入图像描述

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

BufferedReader stdin =
    new BufferedReader(new InputStreamReader( System.in ));
Run Code Online (Sandbox Code Playgroud)

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

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