Java IO中的“ while(-1!=(len = in.read(b)))”和“ while((len = in.read(b))> 0)”之间有什么区别?

时间:2018-09-11 05:17:03

标签: java httpurlconnection java-io

我有这个(有效的)代码:

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),则流无法完成。为什么会这样?

3 个答案:

答案 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