当我知道给定的
InputStream
是否是 buffered以外的东西时,始终将
BufferedInputStream
包装为 InputStream
是否有意义?
例如:
InputStream is = API.getFromSomewhere()
if (!(is instanceof BufferedInputStream)) {
return new BufferedInputStream(is);
}
return is;
当我知道给定的InputStream是否是缓冲以外的东西时,always将InputStream包装为BufferedInputStream是否有意义?
没有。
如果您可能执行大量小读取(一次一个字节或几个字节),或者如果您想使用缓冲 API 提供的一些更高级别的功能,那么这是有意义的;例如
BufferedReader.readLine()
方法。
但是,如果您只想使用
read(byte[])
和/或 read(byte[], int, int)
方法执行大块读取,则将 InputStream
包装在 BufferedInputStream
中并没有帮助。
(回应 @Peter Tillman 对他自己的答案的评论,块读取用例绝对代表超过
InputStream
类的使用的 0.1%!但是,他是正确的,因为它通常是 无害在不需要时使用缓冲 API。)
我不会这样做,我会将其保留在尽可能的最高抽象级别。如果您不打算使用 BufferedStream 的标记和重置功能,为什么还要包装它呢?
如果消费者需要的话,最好把它包裹在那里。
您可能并不总是需要缓冲,因此,答案是否定的,在某些情况下,这只是开销。
“不”还有另一个原因,而且可能更严重。当您在套接字上启用超时时,与网络套接字一起使用时,
BufferedInputStream
(或BufferedReader
)可能会导致不可预测的故障。读取数据包时可能会发生超时。您将无法再访问传输到该点的数据 - 即使您知道存在一些非零字节数(请参阅 java.net.SocketTimeoutException
,它是 java.io.InterruptedIOException
的子类,因此具有 bytesTransferred
变量可用)。
如果您想知道在读取时如何发生套接字超时,只需考虑调用
read(bytes[])
方法,并且包含消息的原始数据包最终被拆分,但其中一个部分数据包被延迟超过超时(或剩余的数据包)超时的一部分)。当再次包装在实现 java.io.DataInput
的内容中时,这种情况可能会更频繁地发生(任何多字节值的读取,例如 readLong()
或 readFully()
或 BufferedReader.readLine()
方法。
请注意,
java.io.DataInputStream
对于具有超时的套接字流来说也是一个不好的候选者,因为它在超时异常方面也表现不佳。
这还取决于您将如何从 InputStream 中读取数据。 如果您打算一次读取一个字符/字节(即 read()),那么 BufferedInputStream 将通过代表您安静地进行批量读取来减少您的开销。 如果您打算一次将其读入 4k 或 8k 字节/字符数组,那么 BufferdInputStream 可能不会给您带来好处。