java - BufferedInputStream.read(byte[] b, int off, int len) 可以返回 0 吗?是否有可能导致这种情况的重要的、损坏的 InputStreams?

标签 java inputstream bufferedinputstream

BufferedInputStream(byte[] b, int off, int len) 有可能吗?返回 0?

READER'S DIGEST VERSION(您可以阅读下面的其余内容,了解上下文,但我认为归结为:) JDK 或常用库(即 Apache Commons、Guava)中是否存在 InputStreams(即 SocketInputStream、CipherInputStream 等) , 不能正确遵守 InputStream.read(byte[],off,len) 的契约(Contract),即使 len != 0 也可能返回“0”?

(注 1:我的兴趣是它是否真的会发生在仅使用 JDK 的代码中,或者可能发生在一些非常常见的 Java 库中,例如 Apache Commons;我正在查看 javadoc 以获取线索,但我也在查看BufferedInputStream 的源代码(Java 7,以防万一),以防某些边缘情况没有正确记录——而且我不完全相信一种或另一种方式,因此我的问题)

(注2:我不是说在一般情况下,len == 0,我的意思是在一般情况下,你传入一个非零数组,你能不能取回0字节?)

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 的重要情况吗? (即 InputStreams 可能返回 0 且 len 非零,因此如果将它们包装在 BufferedInputStream 中,您需要防止返回值为零?——不是某人的个人、损坏的代码,而是需要注意的重要情况,比如在 JDK 或 Apache Commons 或其他东西中。)

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

注意:对于上下文:我发布这个问题是因为我不理解我在提到这个其他问题(Socket reading using BufferedInputStream)时的对话——这可能有助于阅读该问题的背景。

最佳答案

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

This iterated read continues until one of the following conditions becomes true:

[two irrelevant conditions omitted]

  • The available method of the underlying stream returns zero, indicating that further input requests would block.
BufferedInputStream将履行read的契约(Contract)通过直接委托(delegate)给第一个 read 的底层流读取至少一个字节.如果底层流在第一次读取时正确读取了至少一个字节,则契约(Contract)已完成。
只有后续的读取尝试(“迭代读取”)是有条件的,即如果 available 将被跳过返回 0告诉另一个 read尝试会阻止(再次)。

所以底线是BufferedInputStream履行契约(Contract),就像所有其他 JDK 的 InputStream s——据我所知。顺便说一句,如果你想完全读取一个数组,你可以将流包裹在 DataInputStream 中。它提供了 readFully方法。

关于java - BufferedInputStream.read(byte[] b, int off, int len) 可以返回 0 吗?是否有可能导致这种情况的重要的、损坏的 InputStreams?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21166196/

相关文章:

android 将位图转换为缓冲输入流

java - 为什么我的代码无法实时更新 JTextArea?

java - ADF 中的有界任务流与无界任务流

java - 输入流和输出流之间的搜索/替换

java - 返回空 inputStream 的 URLConnection

java - 从 BufferedInputStream 读取 byte[]

java - 将声明变量的字符串(例如 "x+y")转换为 double 作为数学函数

java - java中使用math.random生成一定数量的随机数

java - 如何在 Java EE 环境中管理数据库和文件系统的事务?

java - 需要一种更好的方法从文本文件中读取和存储值