首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么时候阻塞IO块?

什么时候阻塞IO块?
EN

Stack Overflow用户
提问于 2019-04-13 20:25:06
回答 2查看 264关注 0票数 0

InputStream.available() javadoc:

返回可以从此输入流读取(或跳过)而不阻塞的字节数。

  1. 我认为阻塞意味着我调用read()的线程在read()返回之前被阻塞(控制流不会更进一步)。从这个意义上说,我看不到任何可以在不阻塞的情况下调用read()的场景。
  2. 阻塞的另一个含义可能是,如果我想读取3个字节,并且没有或只有1个字节可用,read()会阻塞并等待更多字节的出现--但我无法理解b/c调用read()和尝试读取超过可用的字节可能会导致永久阻塞(只需要从10个字节的文件中读取100个字节)。

在什么意义上java.io是阻塞(1)或(2)?

当使用FileInputStream或ByteArrayInputStream读取IO块的方法(在意义上是(2))时,我无法模拟这样的情况:

代码语言:javascript
复制
        // file content is: 1 2 3       
        FileInputStream myStream = new FileInputStream("d:\\file.txt");
        byte[] b = new byte[100];
        myStream.read(b);
        System.out.println("control reached here?");
        System.out.println(Arrays.toString(b));

输出:

代码语言:javascript
复制
reached here?
[122, 100, 122, 120, 118, 122, 120, 32, 118, 122, 120, 118, 32, 122, 120, 118, 32, 122, 118, 99, 122, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

第二次调用myStream.read(b)只会返回-1也没有阻塞。

在哪种情况下发生阻塞?

我认为,如果我尝试读取5个字节,并且有3个字节,就会发生这种情况。如果没有,它意味着EOF /流结束和-1被返回(也没有阻塞)。

我倾向于认为java.io既是(1)又是(2):它是同步的(1)和阻塞(2),但真正观察到的阻塞只适用于套接字( socketsSocket.getInputStream() / Socket.getOutputStream())。

EN

回答 2

Stack Overflow用户

发布于 2019-04-13 23:40:58

或多或少的选项2,但您不必担心read阻塞,即使已经有一些数据要处理。

这里有个提示:不要使用available()。它实际上是无用的,它所提供的信息并不能真正地让你去做你无法做的事情。

假设您有TCP网络连接。除非您或对方挂断连接,否则不能限制通过行发送多少字节,但另一方面,可能还有10字节需要读取,并且暂时不会有更多的字节出现,因为发送方暂时处于沉默状态。

假设你这样做:

代码语言:javascript
复制
byte[] b = new byte[100];
int r = in.read(b);

这里将要发生的是,r将是10,您的b中的前10个插槽将被填满,就是这样。read‘智能’返回:如果有0字节,它不会返回(read保证它会阻塞,直到它读取至少一个字节,或者流被关闭,在这种情况下,它返回-1).如果有要读取的字节,则读取其中的一个有效块。

具体来说,blocking意味着线程将被暂停,直到某些事情发生变化时才会恢复。(字节进入,或者流关闭)。

票数 1
EN

Stack Overflow用户

发布于 2019-04-13 20:59:26

场景2是意义所在。

(经过一些试验后更新)

本地磁盘文件I/O似乎不被视为阻塞。对于FileInputStream,available()方法返回文件的剩余长度。也就是说,如果文件有91764字节长,并且读取了4个字节,那么在这个可用的()之后将返回91760。

我发现这个结果令人惊讶;如果您尝试读取这91760字节,那么您的线程肯定会阻塞磁盘I/O。

其结果对于网络套接字连接来说更容易理解。当然,将来从远程系统到达的数据量是未知的;available()会告诉您已经到达了多少,现在就可以读取。在这种情况下,“阻塞”将是无限期的--等待远程主机发送,这是I/O系统所不知道的。在离开20字节,可用于进一步读取,而不阻塞。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55669555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档