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

问题描述 投票:1回答:3

我有这个(工作)代码:

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

java httpurlconnection java-io
3个回答
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,则所讨论的两个条件将仅评估为不同的值。但是看,read仅在没有读取字节时返回0,并且是唯一的传入没有字节的时间是传入长度为0的数组:

如果b的长度为零,则不读取任何字节,返回0;否则,尝试读取至少一个字节。如果没有字节可用,因为流位于文件的末尾,则返回值-1;否则,至少读取一个字节并存储到b中。

您的数组具有恒定长度的1024,因此在这种特殊情况下,这两个条件将产生相同的结果。


1
投票

根据documentations方法InputSteam.read(byte[] b)

如果b的长度为零,则不读取任何字节,返回0;否则,尝试读取至少一个字节。如果没有字节可用,因为流位于文件的末尾,则返回值-1;否则,至少读取一个字节并存储到b中。

所以,基本上,当你使用while ((len = in.read(b)) > 0)时,如果read()返回0(意味着最后一个读取字节的长度为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

© www.soinside.com 2019 - 2024. All rights reserved.