Java 我应该总是将 InputStream 包装为 BufferedInputStream 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2964044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should I always wrap an InputStream as BufferedInputStream?
提问by geejay
Does it make sense to always wrap an InputStream as BufferedInputStream, when I know whether the given InputStream is something other than buffered? For e.g:
当我知道给定的 InputStream 是否不是缓冲的东西时,总是将 InputStream 包装为 BufferedInputStream 是否有意义?例如:
InputStream is = API.getFromSomewhere()
if(!(is instanceof BufferedInputStream))
return new BufferedInputStream(is);
return is;
回答by Peter Tillemans
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?
我不会那样做,我会把它留在可能的最高抽象级别。如果您不打算使用 BufferedStream 的标记和重置功能,为什么还要包装它呢?
If a consumer needs it, it is better to wrap it there.
如果消费者需要它,最好将其包装在那里。
回答by Paul Jowett
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.
它还取决于您将如何从 InputStream 读取。如果您打算一次读取一个字符/字节(即 read()),那么 BufferedInputStream 将通过代表您安静地进行批量读取来减少您的开销。如果您打算一次一个块地将它读入 4k 或 8k 字节/字符数组,那么 BuffredInputStream 可能不会使您受益。
回答by Stephen C
Does it make sense to alwayswrap an InputStream as BufferedInputStream, when I know whether the given InputStream is something other than buffered?
当我知道给定的 InputStream 是否不是缓冲的东西时,总是将 InputStream 包装为 BufferedInputStream是否有意义?
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.
如果您可能执行大量小读取(一次一个字节或几个字节),或者您想使用缓冲 API 提供的某些更高级别的功能,那么这是有意义的;例如BufferedReader.readLine()
方法。
However, if you are only going to perform large block reads using the read(byte[])
and / or read(byte[], int, int)
methods, wrapping the InputStream
in a BufferedInputStream
does not help.
但是,如果您只想使用read(byte[])
和/或read(byte[], int, int)
方法执行大块读取,则将InputStream
a包装在 aBufferedInputStream
中无济于事。
(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 harmlessto use a buffered API when you don't need to.)
(为了回应@Peter Tillman 对他自己的答案的评论,块读取用例肯定代表了超过 0.1% 的InputStream
类使用!!但是,他是正确的,因为在以下情况下使用缓冲 API通常是无害的你不需要。)
回答by Kevin Brock
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
(or BufferedReader
) 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 (see java.net.SocketTimeoutException
which is a subclass of java.io.InterruptedIOException
so has bytesTransferred
variable available).
还有另一个原因是“不”,而且可能更严重。BufferedInputStream
(或BufferedReader
) 与网络套接字一起使用时,如果您还启用了套接字超时,则可能会导致不可预测的故障。读取数据包时可能会发生超时。您将不再能够访问被转移到该点的数据-即使你知道,有一些非零字节数(见java.net.SocketTimeoutException
这是一个子类java.io.InterruptedIOException
等具有bytesTransferred
可变可用)。
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 implements java.io.DataInput
(any of the reads for multiple byte values, like readLong()
or readFully()
or the BufferedReader.readLine()
method.
如果您想知道读取时套接字超时是如何发生的,只需考虑调用该read(bytes[])
方法,包含消息的原始数据包最终被拆分,但部分数据包之一延迟超过超时(或超时的剩余部分) )。当再次包装在实现的东西中时,这种情况可能会更频繁地发生java.io.DataInput
(对多个字节值的任何读取,例如readLong()
orreadFully()
或BufferedReader.readLine()
方法。
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.
请注意,java.io.DataInputStream
这对于具有超时的套接字流来说也是一个糟糕的候选者,因为它在超时异常中也表现不佳。