8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Java InputStream阻塞读取

Ben Dove 2月前

285 0

根据 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() 我也希望第一个事件的读取只会阻止第二个事件的读取,但不会擦除或消耗太多的流数据。 为什么这样做会导致我的数据无法全部显示?

帖子版权声明 1、本帖标题:Java InputStream阻塞读取
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Ben Dove在本站《sockets》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 好吧,这有点乱,所以首先让我们澄清一下: InputStream.read() 阻塞与多线程无关。如果您有多个线程从同一个输入流读取数据,并且触发两个彼此非常接近的事件 - 每个线程都试图消费一个事件,那么您就会得到损坏:第一个读取的线程将获得一些字节(可能是所有字节),而当第二个线程被调度时,它将读取其余的字节。如果您计划在多个线程中使用单个 IO 流,则始终要 synchronized() {} 受到一些外部约束。

    其次,如果你可以读取 InputStream 直到得到 -1,然后等待并稍后再次读取,则你使用的 InputStream 实现已损坏! 的契约 InputStream 明确规定, InputStream.read() 只有在没有更多数据可读取时才应返回 -1,因为已经到达流的末尾并且永远不会有更多数据可用 - 就像当你从文件中读取并到达末尾时一样(1).

    “现在没有更多可用数据,请等待,您将获得更多数据”的行为是 read() 阻塞并且直到有可用数据(或引发异常)才返回。

    1. erickson(目前最热门的)答案 的讨论中深入指出的那样 FileInputStream 如果稍后将数据添加到文件中, read() 实现实际上可以读取超过 \'文件末尾\' 的数据,并在 -1 返回 InputStream 实现中唯一这样的情况(或者最坏的情况是 - 非常非常罕见)。如果您知道您使用 FileInputStream 期望您读取的文件添加了其他数据(一个常见的例子是跟踪日志文件),那么您应该考虑到这一点,但除此之外,这只是 API 的缺陷 InputStream 样式阻塞 IO API 并使用 java.io 非阻塞 IO API,那么 java.nio 您会更好
返回
作者最近主题: