繁体   English   中英

Can BufferedInputStream.read(byte [] b,int off,int len)是否会返回0? 是否有重要的,破坏的InputStream可能会导致这种情况?

[英]Can BufferedInputStream.read(byte[] b, int off, int len) ever return 0? Are there significant, broken InputStreams that might cause this?

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字节吗?)

javadoc就在这里 ,部分说:

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的重要情况? (即InputStreams 可能会返回0而非零len,所以如果你将它们包装在BufferedInputStream中,你需要防止零返回值? - 不是某人的个人破损代码,但需要注意的重要案例,在JDK或Apache Commons等中说。)

为长期问题道歉; 在我写这篇文章时,我正在做更多的研究,所以这个问题越来越多。

注意:对于上下文:我发布这个问题是因为我不理解我在参考另一个问题( 使用BufferedInputStream读取套接字 )时的对话 - 它可能有助于阅读该问题的背景。

你没有仔细阅读BufferedInputStream的规范。 你引用了:

迭代读取将继续,直到满足以下条件之一:

[省略了两个不相关的条件]

  • 基础流的可用方法返回零,表示进一步的输入请求将被阻止。

BufferedInputStream将通过直接委托给第一次read的底层流来完成read读取至少一个字节的合同。 如果基础流正确读取第一次读取的至少一个字节,则合同已经完成。

只有后续的读取尝试(“迭代读取”)才是有条件的,即如果available返回0告诉另一次read尝试将再次阻塞。


所以底线是BufferedInputStream履行合同,就像所有其他JDK的InputStream - 据我所知。 顺便说一句,如果你想完全读取一个数组,你可以将流包装在一个提供readFully方法的DataInputStream中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM