首先,我理解缓冲作为包装的概念,例如,FileInuptStream
作为内容读取的临时容器(让我们从上面读取方案),在这种情况下 - FileInputStream
。
read
的{{1}}方法)必须进行100次读取(一次一个字节)。BufferedInputStream
是数据(包含100个字节的文件)的最终来源(尽管由FileInuptStream
包裹),因此不必读取100次以读取100字节?但是,代码调用BufferedInputStream
的{{1}}方法但是,调用会传递给read
BufferedInputStream
方法,该方法需要进行100次读取调用。这是我无法理解的。 IOW,虽然由read
包裹,但基础流(例如FileInuptStream
)仍然必须一次读取一个字节。那么,哪些好处(不是只需要两次读缓冲的代码,而是应用程序的性能)的缓冲?
感谢。
编辑:
我将此作为后续跟踪'编辑'而不是评论'因为我觉得它的上下文更适合这里和作为TL;对于@Kayaman和我之间的聊天读者的DR。
BufferedInputStream
的{{3}}方法说(摘录):
作为额外的便利,它 尝试通过重复调用来读取尽可能多的字节 读取基础流的方法。此迭代读取继续 直到满足下列条件之一:
FileInputStream
我深入研究代码并找到方法调用跟踪,如下所示:
BufferedInputStream
- > The specified number of bytes have been read,
The read method of the underlying stream returns -1, indicating end-of-file, or
The available method of the underlying stream returns zero, indicating that further input requests would block.
我希望看到缓冲行动。BufferedInputStream
- > read(byte b[])
BufferedInputStream
- > read(byte b[], int off, int len)
- 私人BufferedInputStream
-
read(byte b [],int off,int len)read1(byte[] b, int off, int len)
- > FileInputStream
- 私人和本地人。源代码中的方法描述 - 将子数组读取为字节序列。
FileInputStream
中readBytes(byte b[], int off, int len)
(上面提到的#4)的呼叫处于无限read1
循环中。它返回上面BufferedInputStream
方法描述摘录中提到的条件。
正如我在OP(#6)中提到的,调用似乎确实由与API方法描述和方法调用跟踪匹配的基础流处理。
问题仍然存在,如果本地API调用 - for
read
一次读取一个字节并创建要返回的字节数组?
答案 0 :(得分:1)
基础流(例如
FileInputStream
)仍然必须阅读 一次一个字节
幸运的是,那将是非常低效的。它允许BufferedInputStream
对read(byte[8192] buffer)
进行FileInputStream
次调用,这将调用一大块数据。
如果您想要读取单个字节(或不读取),它将从BufferedInputStream's
内部缓冲区有效地返回,而不必转到文件级别。所以BI
可以减少我们从文件系统中实际读取的次数,当这些完成后,即使最终用户只想读取几个字节,它们也会以有效的方式完成。
从代码中可以清楚地看出BufferedInputStream.read()
不直接委托给UnderlyingStream.read()
,因为这会绕过所有缓冲。
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}