构造函数中缓冲区大小的意义是什么?
BufferedReader(Reader in, int size)
正如我编写的程序:
import java.io.*;
class bufferedReaderEx{
public static void main(String args[]){
InputStreamReader isr = null;
BufferedReader br = null;
try{
isr = new InputStreamReader(System.in);
// System.out.println("Write data: ");
// int i = isr.read();
// System.out.println("Data read is: " + i);
//Thus the InputStreamReader is useful for reading the character from the stream
System.out.println("Enter the data to be read by the bufferedReader: ");
//here isr is containing the lnefeed already so this is needed to be flushed.
br = new BufferedReader(isr, 2);
String str = br.readLine();
System.out.println("The data is : :" + str);
}catch(IOException e){
System.out.println("Can't read: " + e.getMessage());
}
}
}
输出:
Enter the data to be read by the bufferedReader: Hello world and hello world again
The data is: Hello world and hello world again
那么缓冲区大小意味着什么,因为我打算只读取两个字符。但事实并非如此。
BufferedReader
缓冲输入,正如其名称所示。这意味着它会先从输入源读取到缓冲区,然后再将其传递给您。这里的缓冲区大小是指它缓冲的字节数。
从大多数来源读取输入非常慢。仅 2 个字节的缓冲区就会损害性能,因为您的程序很可能大部分时间都在等待输入。当缓冲区大小为 2 时,读取 100 个字节将导致从内存缓冲区读取 2 个字节(非常快),填充缓冲区(非常慢),从缓冲区读取 2 个字节(非常快),填充缓冲区缓冲区(非常慢)等 - 总体非常慢。当缓冲区大小为 100 时,读取 100 个字节将导致从内存缓冲区读取 100 个字节(非常快)——总体来说非常快。这是假设读取时缓冲区包含 100 个字节,在像您这样的情况下,这是一个合理的假设。
除非您知道自己在做什么,否则应该使用相当大的默认缓冲区大小。缓冲区较小的原因之一是当您在内存有限的设备上运行时,因为缓冲区会消耗内存。
https://docs.oracle.com/javase/8/docs/api/?java/io/BufferedReader.html
根据此 java 文档,默认缓冲区大小为 8192 个字符容量。 行大小被视为 80 个字符的容量。
8192 缓冲区大小足以满足较小的文件大小。但这又是可以增长的。如果文件包含超过 8192 个字符,则 bufferedreader 的 fill 方法将在从文件读取内容之前增加缓冲区大小。对于较大的内容文件,最好在通过构造函数创建缓冲读取器时设置自己的最大缓冲区大小,这样就可以避免重新创建内存并将旧数组复制到新创建的数组中。
当您读取或写入文件时,您必须访问内核,内核实际上获得了对文件的访问权限。所有的文件操作都必须经过内核。 这是一项相当昂贵的操作。 缓冲导致读取一大块字节;它们保存在 RAM 中的临时位置,并且是从该位置读取的字节。 这样,您就不会频繁请求内核进行文件 IO。
如果您使用巨大的缓冲区大小,您将不必要地占用 RAM。如果您使用一个很小的文件请求,您将不断地对内核进行窃听。 最好允许使用默认值。 您可以指定缓冲区大小和实验。 大多数机器一次会读取一个扇区或整数个扇区。 扇区大小取决于您格式化机器的方式。
下面这个实验很有趣。 创建一个包含 1,000,000 个零的文件。 使用操作系统的计时功能来查看将其复制到另一个文件的速度(您将编写一个带有缓冲和非缓冲 IO 的复制程序)。 使用各种缓冲区大小(包括默认值)对其进行计时。