Java';s缓冲输入流
首先,我理解了缓冲作为包装的概念,例如,Java';s缓冲输入流,java,buffer,bufferedinputstream,Java,Buffer,Bufferedinputstream,首先,我理解了缓冲作为包装的概念,例如,FileInuptStream充当从底层流读取内容的临时容器(让我们采取读取场景),在本例中-FileInputStream 比如说,从一个流(作为源的文件)中读取100个字节 如果没有缓冲,代码(read方法的BufferedInputStream)必须进行100次读取(一次读取一个字节) 使用缓冲时,根据缓冲区大小,代码使读取(字节b[])成为一个我希望看到缓冲作用的例子 BufferedInputStream->读取(字节b[],int off,in
FileInuptStream
充当从底层流读取内容的临时容器(让我们采取读取场景),在本例中-FileInputStream
read
方法的BufferedInputStream
)必须进行100次读取(一次读取一个字节)读取(字节b[])
成为一个我希望看到缓冲作用的例子BufferedInputStream
->读取(字节b[],int off,int len)
BufferedInputStream
->read1(字节[]b,int off,int len)
-专用FileInputStream
-
读取(字节b[],整数关闭,整数长度)FileInputStream
->readBytes(字节b[],int off,int len)
-私有和本机。源代码中的方法说明-BufferedInputStream
中调用read1
(#4,如上所述)处于无限for
循环中。它返回上述read
方法描述摘录中提到的条件
正如我在OP(#6)中提到的,调用似乎是由一个底层流处理的,该流与API方法描述和方法调用跟踪相匹配
问题仍然存在,如果FileInputStream
的本机API调用-readBytes
每次读取一个字节,并创建一个要返回的字节数组
底层流(例如FileInputStream
)仍然必须读取
一次一个字节
幸运的是,这将是非常低效的。它允许BufferedInputStream
对文件输入流进行读取(字节[8192]缓冲区)
调用,该调用将返回一块数据
如果您想读取单个字节(或不读取),它将从BufferedInputStream的
内部缓冲区高效地返回,而不必返回到文件级。因此,BI
可以减少我们从文件系统进行实际读取的时间,当这些读取完成后,即使最终用户只想读取几个字节,也可以高效地进行读取
从代码中可以很清楚地看出,BufferedInputStream.read()
不会直接委托给underyingStream.read()
,因为这样会绕过所有缓冲
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
如果FileInputStream
(及其同级)能够返回数据块,那么缓冲的必要性是什么?因为,返回的数组总是在内存中,可以按照我们的喜好处理。因为如果您确实希望一次读取一个字节,那么您不希望执行100个文件系统操作。你从…缓冲区得到它们!然后,您可以读取任意多或任意少的内容,因为您知道除非需要更多数据,否则文件系统不会受到影响。我理解这一点。我的意思是w.r.t你的答案-它允许BufferedInputStream
对FileInputStream
进行读取(字节[8192]缓冲)调用,该调用将返回一块数据。正如你所说,FileInputStream
将返回一块数据,那么就不清楚为什么有必要使用BufferedInputStream
?我已经在这里的第一条评论中解释过了。它不是关于读取块,而是关于最小化对底层流的调用,无论是文件、套接字还是其他。从缓冲区读取速度更快。这太神奇了。我要说的第一件事是“FileInputStream一次不必读取一个字节”,方法的名称是readBytes
,末尾的S表示复数。但你仍然说它一次读取一个字节。为什么讨论“它能做到这一点?”“不,它不能”“但是……如果它能做到这一点怎么办?”。我将编辑您的问题,以指出示例逻辑中的错误。如果你不想要它,我将回滚更改。现在它完全错了,也许你会对你写的东西感到困惑,这只是你的错误猜测。这是一个方法名,在内部,它可以对硬盘上的文件进行多次读取(一次读取一个字节),并创建一个要返回的数组。2.我不是在猜测,我是按照API方法描述和源代码挖掘来做的。如果底层流(如FileInputStream)确实提供了大容量读/写(实际上由本机调用处理),那么请纠正我的错误,BufferedInputStream
只是一个类似于助手的对象,用于管理内存中的内容。否则,代码必须自行管理标记、重置或任何其他有效机制。所以,现在您终于获得了它!?当所有的大众媒体、文件系统和其他所有东西都以块的形式处理事情时,你是在一次处理一个字节的假设下行事的。
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}