InputStream.available()javadoc:
返回可以在不阻塞的情况下从此输入流中读取(或跳过)的字节数
read()
的线程被阻塞(控制流程不会更进一步),直到read()
返回。从这个意义上讲,我看不到任何可以在不阻塞的情况下调用read()的场景。read()
将阻塞并等待更多字节出现 - 但我不能理解它b / c然后调用read()
和尝试读取超过可用数量可能会导致永久阻塞(只需从10个字节的文件中读取100个字节)。在哪种意义上java.io阻塞(1)或(2)?
当使用FileInputStream或ByteArrayInputStream读取IO块的方法(在sense(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个字节并且有三个字节就会发生。如果没有,则表示EOF / end-of-stream并返回-1(也没有阻塞)。
附:我倾向于认为java.io是(1)和(2):它是同步(1)和阻塞(2),但实际上只能使用套接字(Socket.getInputStream() / Socket.getOutputStream()
)来观察阻塞。
或多或少的选项2,但即使有一些数据要处理,你也不必担心read
阻塞。
这是一个提示:不要使用available()。它实际上是无用的,它授予的信息实际上并没有让你做你不能做的事情。
假设您有TCP网络连接。在您或对方挂断连接之前,可以通过线路发送多少字节没有限制,但另一方面,可能还有10个字节需要读取,不会有更多字节即将发送有一段时间,因为发件人现在是沉默的。
让我们说你然后这样做:
byte[] b = new byte[100];
int r = in.read(b);
这里会发生什么,是r
将是10
,你的b
的前10个位置将被填补,就是这样。 read
'smartly'返回:如果有0个字节,它不返回(读取保证它将阻塞,直到它读取至少1个字节,或者流被关闭,在这种情况下它返回-1
)...并且如果有些字节需要读取,它会读取一小部分内容。
blocking
,具体来说,意味着该线程将被暂停,并且在某些更改之前不会恢复。 (字节进来,或流关闭)。
场景2是意思。
(经过一些实验后更新)
似乎本地磁盘文件I / O不被视为阻塞。对于FileInputStream,available()方法返回文件的剩余长度。也就是说,如果文件长度为91764字节,并且您读取4个字节,那么available()将返回91760。
我发现结果令人惊讶;如果你试图读取那些91760字节,你的线程肯定会阻止磁盘I / O.
结果对于网络套接字连接更容易理解。未来可能从远程系统到达的数据量当然是未知的; available()会告诉你已经到达了多少,现在可以阅读。在这种情况下,“阻塞”将具有无限期的持续时间 - 等待远程主机发送,这在I / O系统的知识之外。在叶子20字节可用于进一步读取而不阻塞。