首先,我理解缓冲作为包装器的概念,例如,FileInuptStream充当从底层流读取内容的临时容器(让我们使用读取场景),在本例中是FileInputStream。
readBufferedInputStream方法)必须进行100次读取(每次一个字节)。FileInuptStream是数据(包含100个字节的文件)的最终源(尽管由BufferedInputStream包装),它不需要读取100次才能读取100个字节吗?虽然,代码调用read方法的BufferedInputStream但是,调用被传递给FileInuptStream的read方法,该方法需要进行100个读取调用。这是我无法理解的观点。IOW虽然被BufferedInputStream封装,但底层流(如FileInputStream)仍然需要一次读取一个字节。那么,缓冲的好处是什么(不是对于只需要两个读调用来缓冲的代码,而是对应用程序的性能)?
谢谢。
编辑:
我把它作为一个后续的‘编辑’而不是‘评论’,因为我认为它的上下文更适合这里,作为一个TL;博士之间的@Kayaman和我之间的聊天读者。
朗读方法BufferedInputStream说(节选):
另外,为了方便起见,它试图通过反复调用底层流的read方法来读取尽可能多的字节。此迭代读取将继续进行,直到下列条件之一变为真为止: 已读取指定数量的字节,底层流的读取方法返回-1,表示文件结束,或者底层流的可用方法返回零,指示进一步的输入请求将被阻塞。
我钻研了代码并找到了如下所示的方法调用跟踪:
BufferedInputStream -> read(byte b[])作为一个我希望看到缓冲在运行中。BufferedInputStream -> read(byte b[], int off, int len)BufferedInputStream -> read1(byte[] b, int off, int len) -私有FileInputStream -read(字节b[],int off,int len)FileInputStream -> readBytes(byte b[], int off, int len) -私有的和本地的。方法描述来自源代码-将子数组读取为字节序列。
在read1中调用BufferedInputStream (上面提到的#4)处于无限for循环中。它在上述read方法描述的摘录中提到的条件下返回。
正如我在OP(#6)中提到的,调用似乎是由一个与API方法描述和方法调用跟踪相匹配的底层流处理的。
问题仍然存在,如果本机API调用- readBytes of FileInputStream一次读取一个字节并创建一个这些字节的数组返回呢?
发布于 2018-04-05 12:38:19
底层流(如
FileInputStream)仍然必须一次读取一个字节。
幸运的是,没有,这将是非常低效的。它允许BufferedInputStream对FileInputStream进行read(byte[8192] buffer)调用,这将返回一块数据。
如果您想读取单个字节(或不读取),那么它将有效地从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;
}https://stackoverflow.com/questions/49672561
复制相似问题