我有这个(有效的)代码:
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)
,则流无法完成。为什么会这样?
答案 0 :(得分:1)
乍一看,这两个条件可能看起来非常不同。让我们重新排列它们,以使(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,则所讨论的两个条件将求值为不同的值。但是,{{ 1}}仅在不读取任何字节时才返回0,并且只有当您传入长度为0的数组时才不读取字节:
如果b的长度为零,则不读取任何字节,并返回0;否则,返回0。 否则,尝试读取至少一个字节。如果没有字节 可用,因为流位于文件的末尾,该值 -1返回;否则,将读取至少一个字节并将其存储到b中。
您的数组的长度恒定为read
,因此在这种情况下,两个条件将产生相同的结果。
答案 1 :(得分:1)
根据方法InputSteam.read(byte[] b)
的{{3}}:
如果b的长度为零,则不读取任何字节,并返回 0 ; 否则,尝试读取至少一个字节。如果没有字节 可用,因为流位于文件的末尾,该值 -1返回;否则,将读取至少一个字节并将其存储到b中。
因此,基本上,当您使用while ((len = in.read(b)) > 0)
时,如果read()
返回0(意味着最后一个读取字节的长度为0),即使流的末尾没有返回0,您也将退出循环。已到达,因此仍然有待读取的数据(流未完成)。
答案 2 :(得分: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