【问题标题】:How BufferedInputStream makes the read operation faster?BufferedInputStream 如何使读取操作更快?
【发布时间】:2013-07-02 16:05:09
【问题描述】:
我知道将 BufferedInpurStream 包裹在 FileInputStream 周围会使读取操作更快,但尝试
弄清楚如何。我查看了 BufferedInpurStream 的源代码并得到了一些东西。这是我的
理解
InputStream in = new BufferedInpurStream(new FileInputStream(filename));
int byteToRead;
while((byteToRead = in.read()) != -1)
当我执行 bufferedInpurStream.read() 时,在内部,它会先将字节块一次读入缓冲区,然后
从缓冲区中逐个读取每个字节,而不是从文件中读取(成本更高)。一旦缓冲区为空
它会再次用大块字节填充它
在使用 FileInputStream.read() 时,从文件中逐个字节地执行读取操作,这是非常昂贵的
这种理解正确吗?
【问题讨论】:
标签:
java
bufferedinputstream
【解决方案1】:
是的。正如您所描述的,BufferedInputStream 极大地减少了从流中一次读取一个字节时进行的 IO 调用次数(因为大多数 read() 调用都命中了缓冲区)。
【解决方案2】:
通常,read(byte[] b)(或 read(byte[] b, int off, int len)) 比 read() 更受欢迎,因为它可能具有一些 IO 性能优势。
如果你使用 read(byte[] b),BufferedInpurStream 没有实际优势,只要你使用相同的缓冲区大小。
void read(InputStream inputStream, int bufferSize) throws IOException
{
byte[] buffer = new byte[bufferSize];
int read;
while ((read = inputStream.read(buffer)) != -1)
{
// do some work
}
}
和
void read2(InputStream inputStream, int bufferSize) throws IOException
{
BufferedInputStream bis = new BufferedInputStream(inputStream, bufferSize);
try
{
byte[] buffer = new byte[bufferSize];
int read;
while ((read = bis .read(buffer)) != -1)
{
// do some work
}
}
finally
{
bis.close();
}
}
尝试阅读和阅读2。您会发现,只要您使用适当的缓冲区大小,Wrapping to BufferedInputStream 并不会提高性能。 (实际上它会产生另一个计算成本......)
那么,什么时候需要 BufferedInputStream?
这是我的建议:
- 如果您知道“合适的”缓冲区大小,请直接处理。它产生更短的代码。
(例如:文件读取。您可以使用文件大小作为缓冲区大小。)
- 如果您不知道“适当的”缓冲区大小,或者您必须将 InputStream 传递给另一个库,请将流包装为 BufferedInputStream。
您可能会从缓冲中受益。 (例如:Web 文件传输。服务器可能不提供内容长度字段。)