Java InputStream 阻塞读取

标签 java blocking inputstream rxtx java-io

根据java api,InputStream.read()描述为:

If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

我有一个 while(true) 循环进行读取,当没有任何内容通过流发送时,我总是得到 -1。这是意料之中的。

我的问题是 read() 什么时候会阻塞?因为如果它没有得到任何数据,它会返回-1。我希望阻塞读取要等到收到数据。如果您已到达输入流的末尾,难道 read() 不应该只是等待数据而不是返回 -1 吗?

或者 read() 只有在有另一个线程访问流并且您的 read() 无法访问流时才会阻塞?


这引出了我的下一个问题。我曾经有事件监听器(由我的库提供),它会在数据可用时通知我。当我收到通知时,我会调用 while((aByte = read()) > -1) 存储字节。当我在非常接近的时间内获得两个事件并且并未显示我的所有数据时,我感到很困惑。似乎只有第二个事件的数据的尾部会显示,其余的都不见了。

我最终更改了我的代码,以便当我收到一个事件时,我会调用 if(inputStream.available() > 0) while((aByte = read()) > -1) 存储字节。现在它工作正常,我的所有数据都显示出来了。

有人可以解释这种行为吗? InputStream.available() 据说返回在阻塞下一个调用者(流的?)之前可以读取的字节数。即使我不使用 .available() 我希望读取第一个事件只会阻止读取第二个事件,但不会删除或消耗太多流数据。为什么这样做会导致无法显示我的所有数据?

最佳答案

InputStream 的某些实现的底层数据源可以发出已到达流末尾的信号,不再发送数据。在接收到此信号之前,对此类流的读取操作可能会阻塞。

例如,来自 Socket 套接字的 InputStream 将阻塞,而不是返回 EOF,直到收到设置了 FIN 标志的 TCP 数据包。当从这样的流中接收到 EOF 时,您可以确信在该套接字上发送的所有数据都已被可靠地接收,并且您将无法再读取任何数据。 (另一方面,如果阻塞读取导致异常,则可能会丢失一些数据。)

其他流,例如来自原始文件或串行端口的流,可能缺少类似的格式或协议(protocol),以表明没有更多数据可用。当当前没有数据可用时,此类流可以立即返回 EOF (-1) 而不是阻塞。但是,在没有这种格式或协议(protocol)的情况下,您无法确定对方何时完成发送数据。


关于你的第二个问题,听起来你可能有竞争条件。在没有看到有问题的代码的情况下,我猜测问题实际上在于您的“显示”方法。也许第二个通知显示的尝试以某种方式破坏了第一个通知期间完成的工作。

关于Java InputStream 阻塞读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/611760/

相关文章:

javascript - Javascript 中的模态阻止对话框

java - 如何以正确的方式捕获空指针异常

java - Java 在 Rust 中的 final 是什么?

java - 这种神秘的颜色方法有什么作用?它返回什么?

C# : Blocking a function call until condition met

java - 当使用空缓冲区调用 read() 时,PipedInputStream 总是阻塞。有什么办法可以阻止这种情况吗?

c++ - 输入缓冲如何在 C++ 中工作

java - getResourceAsStream() 总是返回 null

java - 如何判断套接字是否已断开连接(Java)

java - mongoDB:数组中不存在的文档的 $inc