根据 Java api 文档,在 InputStream 中声明的 read() 方法描述如下:如果由于已到达流末尾而没有可用的字节,则值为 -1
根据 Java api文档 , read()
中声明的 InputStream
描述如下:
如果由于已到达流末尾而没有可用的字节,则返回值 -1。此方法将阻塞,直到输入数据可用、检测到流末尾或引发异常。
我有一个 while(true)
循环 read()
,当流中没有发送任何内容时,我总是得到 -1。这是意料之中的。
我的问题是什么时候会 read()
阻塞?因为如果它没有收到任何数据,它会返回 -1。我期望阻塞 read()
会等到收到数据。如果您已经到达输入流的末尾,难道不应该 read()
只是等待数据而不是返回 -1 吗?
或者 read()
仅当有另一个线程访问该流而您 read()
无法访问该流时才会阻塞?
这就引出了我的下一个问题。我曾经有一个事件监听器(由我的库提供),当数据可用时它会通知我。当我收到通知时,我会开始 while((aByte = read()) > -1)
循环存储字节。当我在很短的时间内收到两个事件并且并非所有数据都显示出来时,我感到很困惑。似乎只有第二个事件的数据的尾部会显示出来,其余数据都丢失了。
我最终修改了我的代码,这样当我收到事件时,我就开始 if(inputStream.available() > 0) while((aByte = read()) > -1)
存储字节。现在它工作正常,我的所有数据都显示出来。
有人能解释一下这种行为吗? 的 available()
方法 InputStream
据说返回在阻止下一个调用者(流的调用者?)之前可以读取的字节数。 即使我不使用, available()
我也希望第一个事件的读取只会阻止第二个事件的读取,但不会擦除或消耗太多的流数据。 为什么这样做会导致我的数据无法全部显示?
某些实现的底层数据源 InputStream
可以发出信号,表示已到达流的末尾,并且不会再发送任何数据。在收到此信号之前,此类流上的读取操作可能会阻塞。
例如, InputStream
中的 Socket
将会阻塞,而不是返回 EOF,直到收到设置了 FIN 标志的 TCP 数据包。当从这样的流中收到 EOF 时,您可以确保已可靠地接收了该套接字上发送的所有数据,并且您将无法再读取任何数据。(另一方面,如果阻塞读取导致异常,则可能丢失一些数据。)
其他流(例如来自原始文件或串行端口的流)可能缺乏类似的格式或协议来指示不再有可用数据。此类流可以立即返回 EOF(-1),而不是在当前没有可用数据时阻塞。但是,如果没有这样的格式或协议,您无法确定另一端何时发送完数据。
关于你的第二个问题,听起来你可能遇到了竞争条件。在没有看到相关代码的情况下,我猜问题实际上出在你的“display”方法上。也许第二个通知的显示尝试以某种方式破坏了第一个通知期间完成的工作。