41

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

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

4 回答 4

35

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

不。

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

read(byte[])但是,如果您只打算使用and / or方法执行大块读取read(byte[], int, int),则将 a 包装InputStream在 aBufferedInputStream中没有帮助。

(针对@Peter Tillman 对他自己的回答的评论,块读取用例绝对代表超过 0.1% 的类使用!!但是,他是正确的,因为在以下情况下使用缓冲 APIInputStream通常是无害的你不需要。)

于 2010-06-03T10:16:51.923 回答
6

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

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

于 2010-06-03T07:44:53.710 回答
3

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

还有另一个原因是“不”,而且可能更严重。BufferedInputStream(或BufferedReader)与网络套接字一起使用时,如果您还启用了套接字超时,则可能会导致不可预知的故障。读取数据包时可能会发生超时。您将不再能够访问传输到该点的数据 - 即使您知道有一些非零字节数(查看java.net.SocketTimeoutException哪个是java.io.InterruptedIOExceptionso 的子类有bytesTransferred可用的变量)。

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

请注意,java.io.DataInputStream对于具有超时的套接字流来说,这也是一个不好的候选者,因为它在超时异常时也表现不佳。

于 2010-06-03T11:20:19.137 回答
0

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

于 2010-06-03T07:56:40.877 回答