我应该始终将 InputStream 包装为 BufferedInputStream 吗?
当我知道给定的 InputStream
是否不是缓冲的时,始终将 InputStream
包装为 BufferedInputStream
是否有意义嗯>?
例如:
InputStream is = API.getFromSomewhere()
if (!(is instanceof BufferedInputStream)) {
return new BufferedInputStream(is);
}
return is;
Does it make sense to always wrap an InputStream
as BufferedInputStream
, when I know whether the given InputStream
is something other than buffered?
For example:
InputStream is = API.getFromSomewhere()
if (!(is instanceof BufferedInputStream)) {
return new BufferedInputStream(is);
}
return is;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
;
如果您可能执行大量小型读取(一次一个字节或几个字节),或者如果您想使用缓冲 API 提供的一些更高级别的功能,那么这是有意义的 例如 BufferedReader.readLine() 方法。
但是,如果您只想使用 read(byte[]) 和/或 read(byte[], int, int) 方法执行大块读取,则包装
BufferedInputStream
中的InputStream
没有帮助。回应@Peter Tillman的评论他自己的答案。
块读取用例绝对占
InputStream
类使用的 0.1% 以上!然而,他是正确的,因为在不需要时使用缓冲 API 通常是无害的。No.
It makes sense if you are likely to perform lots of small reads (one byte or a few bytes at a time), or if you want to use some of the higher level functionality offered by the buffered APIs; for example the
BufferedReader.readLine()
method.However, if you are only going to perform large block reads using the
read(byte[])
and / orread(byte[], int, int)
methods, wrapping theInputStream
in aBufferedInputStream
does not help.In response to @Peter Tillman's comment on his own answer.
The block read use-cases definitely represent more than 0.1% of uses of
InputStream
classes!! However, he is correct in the sense that it is usually harmless to use a buffered API when you don't need to.我不会这样做,我会将其保留在尽可能的最高抽象级别。如果您不打算使用 BufferedStream 的标记和重置功能,为什么要费心包装它呢?
如果消费者需要它,最好将其包装在那里。
I would not do that, I would leave it at the highest abstraction level possible. If you are not going to use the mark and reset capabilities of a BufferedStream, why bother wrapping it?
If a consumer needs it, it is better to wrap it there.
您可能并不总是需要缓冲,因此,答案是否定的,在某些情况下,这只是开销。
说“不”还有另一个原因,而且可能更严重。当您在套接字上启用超时时,
BufferedInputStream
(或BufferedReader
)与网络套接字一起使用时可能会导致不可预测的失败。读取数据包时可能会发生超时。您将无法再访问传输到该点的数据 - 即使您知道存在一些非零字节数(请参阅 java.net.SocketTimeoutException 的子类)java.io.InterruptedIOException
因此有bytesTransferred
变量可用)。如果您想知道读取时如何发生套接字超时,只需考虑调用 read(bytes[]) 方法,并且包含消息的原始数据包最终被分割,但部分数据包之一延迟超过超时(或超时的剩余部分)。当再次包装在实现 java.io.DataInput 的内容中时,这种情况可能会更频繁地发生(任何多字节值的读取,例如 readLong() 或 readFully () 或
BufferedReader.readLine()
方法请注意,
java.io.DataInputStream
也不适合具有超时的套接字流。对于超时异常也表现不佳。You may not always need buffering so, for that, the answer would be No, in some cases it's just overhead.
There is another reason it is "No" and it can be more serious.
BufferedInputStream
(orBufferedReader
) can cause unpredictable failures when used with network socket when you also have enabled a timeout on the socket. The timeout can occur while reading a packet. You would no longer be able to access the data that were transferred to that point - even if you knew that there was some non-zero number of bytes (seejava.net.SocketTimeoutException
which is a subclass ofjava.io.InterruptedIOException
so hasbytesTransferred
variable available).If you are wondering how a socket timeout could occur while reading, just think of calling the
read(bytes[])
method and the original packet that contains the message ended up being split but one of the partial packets is delayed beyond the timeout (or the remaining portion of the timeout). This can happen more frequently when wrapped again in something that implementsjava.io.DataInput
(any of the reads for multiple byte values, likereadLong()
orreadFully()
or theBufferedReader.readLine()
method.Note that
java.io.DataInputStream
also is a bad candidate for socket streams that have a timeout since it doesn't behave well with timeout exceptions either.它还取决于您将如何从 InputStream 中读取数据。如果您打算一次读取一个字符/字节(即 read()),那么 BufferedInputStream 将通过代表您安静地进行批量读取来减少您的开销。如果您打算一次将其读入 4k 或 8k 字节/字符数组,那么 BufferdInputStream 可能不会给您带来好处。
It also depends on how you are going to read from the InputStream. If you are going to read it a character/byte at a time (ie read()), then the BufferedInputStream will reduce your overheads by queitly doing bulk reads on your behalf. If you are going to read it into a 4k or 8k byte/char array a block at a time then the BuffredInputStream probably won't benefit you.