BufferedInputStream(byte[] b, int off, int len)
是否有可能返回0?
READER'S DIGEST VERSION(你可以阅读下面的内容,对于上下文,但我认为可归结为这个:)是否存在InputStreams(即JDK中的SocketInputStream,CipherInputStream等或常用库(即Apache Commons) ,Guava),没有正确地遵守InputStream.read(byte [],off,len)的合同,即使len!= 0也可能返回'0'?
(注1:我感兴趣的是它是否真的可以在仅使用JDK的代码中发生,或者可能是一些非常常见的Java库,例如Apache Commons;我正在查看javadoc的线索,但我也是查看BufferedInputStream的源代码(Java 7,如果它很重要),以防某些边缘情况没有正确记录 - 我并不完全相信这种或那种方式,因此我的问题)
(注2:我不是指在平凡的情况下,len == 0,我的意思是在一般情况下,你传入一个非零数组,你能回到0字节吗?)< / p>
javadoc是here,它部分地说:
This method implements the general contract of the *corresponding* [my emphasis added] read method of the InputStream class. As an additional convenience, it attempts to read as many bytes as possible by repeatedly invoking the read method of the underlying stream. This iterated read continues until one of the following conditions becomes true:
[省略了两个不相关的条件]
- The available method of the underlying stream returns zero, indicating that further input requests would block.
然后返回值的文档说:
Returns: the number of bytes read, or -1 if the end of the stream has been reached.
所以:通过我的阅读,当你调用这个读取函数时,如果没有缓冲数据和,则可能没有来自底层InputStream
的数据(例如,来自一个停滞的http传输,)然后read方法应该返回0,因为读取了0个字节。
然而......一群似乎比我更了解这一点的人似乎相信这种读取方法总会返回EOF或至少一个字节。
所以,我进一步研究了InputStream,看看the general contract of the corresponding read method of the InputStream class
到底意味着什么,我发现了这个:
If len is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt to read at least one byte. If no byte is available because the stream is at end of file, the value -1 is returned; otherwise, at least one byte is read and stored into b.
所以,根据javadocs ,我认为这意味着BufferedInputStream 不应该返回0.如果我只看文档,我想我会完成现在
但是:经过检查,在我看来,BufferedInputStream的实现并不真正保证一个字节或更多字节;它依赖于底层InputStream的正确行为来继承此保证。抽象InputStream的源似乎得到了这个保证正确(我认为如果len == 0它只能返回0个字节)但是我不知道JDK中的所有输入流是否都是这样,更不用说所有输入流了任何地方。
因此。 我认为我到目前为止的地方是:BufferedInputStream永远不会返回0 ,除非包装的InputStream不支持1个或更多字节的保证 - 但我不知道知道这有多常见。
1)我的一般分析是否正确?
2)有没有人知道InputStreams可以返回0的重要情况? (即,可能返回0且具有非零len的InputStream,因此如果将它们包装在BufferedInputStream中,则需要防止零返回值? - 不是某人的个人破坏代码,但需要注意的重要案例,比如JDK或Apache Commons等。)
为长期问题道歉;在我写这篇文章的时候,我正在做更多的研究,所以问题就越来越多了。
注意:对于上下文:我发布此问题是因为我不理解我在参考其他问题(Socket reading using BufferedInputStream)时的对话 - 这可能有助于阅读该问题的背景。 / p>
答案 0 :(得分:0)
您没有仔细阅读BufferedInputStream
的规范。你引用了:
此迭代继续读取,直到满足以下条件之一:
[省略了两个不相关的条件]
- 基础流的可用方法返回零,表示进一步的输入请求将被阻止。
BufferedInputStream
将通过直接委派给第一个read
的基础流来履行read
读取至少一个字节的合同。如果基础流正确读取了第一次读取的至少一个字节,则合同已经完成。
只有后续的读取尝试(“迭代读取”)才是有条件的,即如果available
返回0
告诉另一个read
尝试将阻止(再次),将跳过。{ p>
所以最重要的是BufferedInputStream
履行合同,就像我所知道的所有其他JDK的InputStream
一样。顺便说一下,如果你想完全读取一个数组,你可以将流包装在一个提供readFully
方法的DataInputStream
中。