InputStream.available()javadoc:
返回可以从中读取(或跳过)的字节数 此输入流无阻塞
我认为阻塞意味着阻塞了我叫read()
的线程(控制流不会继续进行),直到read()
返回。从这个意义上讲,我看不到任何可以不阻塞地调用read()的情况。
阻塞的另一种含义可能是,如果我想读取3个字节而又没有或只有1个字节可用,read()
会阻塞并等待更多的字节出现-但我不明白那样,b / c然后调用read()
并尝试读取超出可用范围的内容可能会导致永久性阻塞(只是想像一下要从10个字节的文件中读取100个字节)。
java.io在哪种意义上阻止了(1)或(2)?
当使用FileInputStream或ByteArrayInputStream读取IO块的方法(在意义上为(2))时,我无法模拟这种情况:
// 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));
输出:
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(也不会阻塞)。
P.S。我倾向于认为 java.io既是(1)又是(2):它既是同步的(1)又是阻塞的(2),但是实际上只有在使用套接字的情况下才观察到阻塞({{ 1}})。
答案 0 :(得分:1)
选项2或多或少,但是即使已经有一些数据需要处理,您也不必担心read
会阻塞。
提示:不要使用available()。它实际上是无用的,它所授予的信息并不能真正让您完成您原本无法做到的事情。
假设您有一个TCP网络连接。在您或另一端挂断连接之前,对可以跨行发送多少字节没有限制,但是在另一面,有可能剩下10个字节要读取,并且以后将不再发送有一阵子是因为发件人现在暂时保持沉默。
假设您然后执行此操作:
byte[] b = new byte[100];
int r = in.read(b);
这里将要发生的是,r
将为10
,b
中的前10个插槽将被填充,仅此而已。 read
“聪明”地返回:如果有0个字节,则不返回(读保证它会阻塞,直到它读取至少1个字节或关闭流,在这种情况下,它返回{{1 }})...,如果有要读取的字节,它将读取其中的有效块。
-1
尤其是意味着该线程将被暂停,并且直到发生更改后才恢复。 (字节进入,或流关闭)。
答案 1 :(得分:0)
场景2就是这个意思。
(经过一些实验后更新)
似乎本地磁盘文件I / O不被视为阻塞。对于FileInputStream,available()方法返回文件的剩余长度。也就是说,如果文件的长度为91764字节,并且您读取了4个字节,则该available()将返回91760。
我发现结果令人惊讶;如果您尝试读取91760字节,则线程肯定会阻塞磁盘I / O。
对于网络套接字连接,结果更易于理解。当然,将来可能从远程系统到达的数据量是未知的。 available()会告诉您有多少已经到达,现在可以读取。在这种情况下,“阻塞”将具有不确定的持续时间-等待直到远程主机可以发送为止,这超出了I / O系统的知识。 at留下20个字节可用于进一步读取而不会阻塞。