很抱歉,如果这个问题很复杂,但我找不到我想要的答案。
Java docs说这个
通常,由Reader构成的每个读取请求都会导致对基础字符或字节流进行相应的读取请求。因此建议将BufferedReader包装在任何read()操作可能代价高昂的Reader上,例如FileReaders>和InputStreamReaders。例如,
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
将缓冲指定文件的输入。如果没有缓冲,read()或readLine()的每次调用都可能导致从文件中读取字节,转换为字符,然后返回,这可能是非常低效的。
我的第一个问题是如果bufferedReader可以读取字节,那么为什么我们不能使用bufferedreader处理以字节为单位的图像。
我的第二个问题是 Bufferedreader是否在BUFFER中存储字符以及此行的含义
将缓冲指定文件的输入。
通常,每个读取请求都会导致相应的读取请求由基础字符或字节流构成。
答案 0 :(得分:7)
这里有两个问题。
<强> 1。缓冲强>
想象一下,你离最近的水源一英里,你每小时喝一杯水。好吧,你不会为每一杯都一直走到水边。每天去一次,然后带着一桶装满水的桶回家24次。
存储桶是缓冲区。
想象一下,你的村庄是河边的供水。但有时河水干了一个月;其他时候,河流带来了如此多的水,村庄洪水泛滥。所以你建造了一座大坝,在大坝后面有一个水库。水库在雨季填满,并在旱季逐渐清空。这个村庄全年都有稳定的水流。
水库是缓冲区。
计算中的数据流与这两种情况类似。例如,您可以在单个OS系统调用中从文件系统获取几千字节的数据,但是如果您希望一次处理一个字符,则需要类似于库的内容。
BufferedReader包含另一个Reader(例如FileReader),它是河流 - 以及一个字节数组,它是一个库。每次你读它,它都会像:
if there are not enough bytes in the "reservoir" to fulfil this request
top up the "reservoir" by reading from the underlying Reader
endif
return some bytes from the "reservoir".
然而当你使用 BufferedReader时,你不需要知道 它是如何工作的,只是它有效。
<强> 2。适用于图像
了解BufferedReader和FileReader是读者的示例非常重要。您可能还没有在编程教育中涵盖多态性,所以当您这样做时,请记住这一点。这意味着如果您的代码使用FileReader
- 但只有符合Reader
的方面 - 那么您可以替换BufferedReader
,它将起到同样的作用。
将变量声明为最常用的类是一个好习惯:
Reader reader = new FileReader(file);
...因为这将是您添加缓冲所需的唯一更改:
Reader reader = new BufferedReader(new FileReader(file));
我绕道而行,因为所有Reader
都不太适合图像。
Reader
有两种read
方法:
int read(); // returns one character, cast to an int
int read(char[] block); // reads into block, returns how many chars it read
第二种形式不适合图像,因为它肯定会读取字符,而不是整数。
第一个表单看起来好像可以 - 毕竟,它读取整数。事实上,如果您只使用FileReader,它可能会有效。
但是,请考虑一下围绕FileReader的BufferedReader如何工作。第一次调用BufferedReader.read()时,它将调用FileReader.read(缓冲区)来填充其缓冲区。然后它会将缓冲区的第一个char
强制转换回int,然后返回。
特别是当您将多字节字符集带入图片时,可能会导致问题。
因此,如果您想要读取整数,请使用InputStream
而不是Reader
。 InputStream
有int read(byte[] buf, int offset, int length)
- 来自int的字节比字符更可靠地来回转换。
答案 1 :(得分:4)
java中的读者(和写作者)是处理文本(字符)流的专用类 - 在任何其他类型的流中,行的概念都是无意义的。
对于通用IO等效项,请查看BufferedInputStream
所以,回答你的问题:
答案 2 :(得分:3)
默认行为是它会转换为字符,但是当你有一个图像时,你不能拥有字符数据,而是需要像素字节数据。所以你不能使用它。
它是buffereing,意思是它正在读取char数组中的某个数据块。您可以在代码中看到此行为:
public BufferedReader(Reader in) { this(in, defaultCharBufferSize); }
,defaultCharBufferSize如下所述:
private static int defaultCharBufferSize = 8192;
3 Every time you do read operation, it will be reading only one character.
因此简而言之,buffred意味着,它将首先读取少量字符数据,这些数据将保留在char数组中并且将被处理,并且它将再次读取相同的数据块,直到它到达流的末尾
您可以参考以下内容了解更多信息