我应该总是将InputStream包装为BufferedInputStream吗?

时间:2010-06-03 07:36:05

标签: java stream java-io

当我知道给定的InputStream是否不是缓冲的时候,总是将InputStream包装为BufferedInputStream是否有意义?例如:

InputStream is = API.getFromSomewhere()
if(!(is instanceof BufferedInputStream))
  return new BufferedInputStream(is);
return is;

4 个答案:

答案 0 :(得分:33)

  

当我知道给定的InputStream是否不是缓冲的时候总是将InputStream包装为BufferedInputStream是否有意义?

没有

如果您可能执行大量小读取(一次一个字节或几个字节),或者如果您想使用缓冲API提供的某些更高级别功能,那么这是有意义的;例如BufferedReader.readLine()方法。

但是,如果您只是使用read(byte[])和/或read(byte[], int, int)方法执行大块读取,则将InputStream包裹在BufferedInputStream中无济于事。

(回应@Peter Tillman对自己的答案的评论,块读取用例肯定代表InputStream类使用的0.1%以上!!但是,他是正确的,因为它是通常无害在您不需要时使用缓冲的API。)

答案 1 :(得分:6)

我不会这样做,我会把它留在最高的抽象级别。如果您不打算使用BufferedStream的标记和重置功能,为什么还要包装呢?

如果消费者需要它,最好将它包装在那里。

答案 2 :(得分:2)

你可能并不总是需要缓冲,因此,答案是否定的,在某些情况下它只是开销。

另一个原因是“不”,而且可能更严重。当您在套接字上启用超时时,BufferedInputStream(或BufferedReader)在与网络套接字一起使用时可能会导致不可预测的故障。读取数据包时可能会发生超时。您将无法再访问传输到该点的数据 - 即使您知道存在一些非零的字节数(请参阅java.net.SocketTimeoutException这是java.io.InterruptedIOException的子类,所以bytesTransferred变量可用)。

如果您想知道在读取时如何发生套接字超时,只需考虑调用read(bytes[])方法,并且包含该消息的原始数据包最终被拆分,但其中一个部分数据包延迟超过超时(或超时的剩余部分)。当再次包含在实现java.io.DataInput的内容中时(包括readLong()readFully()BufferedReader.readLine()方法的多个字节值的任何读取),这种情况可能会更频繁地发生。

请注意,java.io.DataInputStream对于具有超时的套接字流也是一个不好的候选者,因为它对超时异常也不起作用。

答案 3 :(得分:0)

这还取决于您将如何从InputStream中读取。如果您要一次读取一个字符/字节(即read()),那么BufferedInputStream将通过代表您进行批量读取来减少您的开销。如果你打算一次将它读入一个4k或8k字节/ char数组,那么BuffredInputStream可能不会让你受益。