我有这个(工作)代码:
BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
byte[] b = new byte[1024];
int len;
while (-1 != (len = in.read(b))) {
fos.write(b, 0, len);
}
fos.flush();
但是,如果我将while (-1 != (len = in.read(b)))
更改为while ((len = in.read(b)) > 0)
,则流无法完成。为什么是这样?
乍一看,这两个条件可能看起来非常不同。让我们重新安排它们,以便(len = in.read(b))
始终在左边:
(len = in.read(b)) != -1
(len = in.read(b)) > 0
表达式(len = in.read(b))
评估为in.read(b)
。因此,两个条件之间的唯一区别是第一个检查read
是否不返回-1,而第二个检查read
是否返回大于0的值。
我们来看看what read
can return:
返回:
读入缓冲区的总字节数,如果由于已到达流末尾而没有更多数据,则返回-1。
这意味着read
不返回小于-1的任何值,这反过来意味着如果read
返回0,则所讨论的两个条件将仅评估为不同的值。但是看,read
仅在没有读取字节时返回0,并且是唯一的传入没有字节的时间是传入长度为0的数组:
如果b的长度为零,则不读取任何字节,返回0;否则,尝试读取至少一个字节。如果没有字节可用,因为流位于文件的末尾,则返回值-1;否则,至少读取一个字节并存储到b中。
您的数组具有恒定长度的1024
,因此在这种特殊情况下,这两个条件将产生相同的结果。
根据documentations方法InputSteam.read(byte[] b)
:
如果b的长度为零,则不读取任何字节,返回0;否则,尝试读取至少一个字节。如果没有字节可用,因为流位于文件的末尾,则返回值-1;否则,至少读取一个字节并存储到b中。
所以,基本上,当你使用while ((len = in.read(b)) > 0)
时,如果read()
返回0(意味着最后一个读取字节的长度为0),则退出循环,即使尚未到达流的末尾,因此仍有数据被读取(流未完成)。
你完全改变了条件规则。第一个语句检查值完全不匹配-1,因此您的新条件应满足值在(-infinity,-1)和(-1,infinity)范围内的要求
(-1 != (len = in.read(b))) // read until reach end of stream
(len = in.read(b)) > 0) // read until data are present but this is wrong
将其更改为:
(len = in.read(b)) >= 0)
我不知道为什么要改变这种情况。正如文档所说:
返回读取的字节数,如果已到达流的末尾,则返回-1。
形势描述here