В чем разница между "while (-1! = (Len = in.read (b)))" и "while ((len = in.read (b))> 0)" в Java IO? - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть этот (рабочий) код:

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 голосов
/ 11 сентября 2018

На первый взгляд, эти два условия могут показаться очень разными.Давайте переставим их так, чтобы (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.

Давайте рассмотрим что read может вернуть :

Возвращает:

общее количество байтов, считанных в буфер, или -1, если естьбольше нет данных, потому что достигнут конец потока.

Это означает, что read не возвращает ничего меньше -1, что, в свою очередь, означает, что два рассматриваемых условия будут оценивать толькок другим значениям, если read возвращает 0. Но посмотрите, read возвращает 0, только когда байт не читается, и единственный раз, когда байт не читается, это когда вы передаете массив длиной 0:

Если длина b равна нулю, то байты не читаются и возвращается 0;в противном случае предпринимается попытка прочитать хотя бы один байт.Если байт недоступен, поскольку поток находится в конце файла, возвращается значение -1;в противном случае, по крайней мере один байт считывается и сохраняется в b.

Ваш массив имеет постоянную длину 1024, поэтому в данном конкретном случае два условия приведут к одинаковым результатам.

0 голосов
/ 11 сентября 2018

Согласно документации для метода InputSteam.read(byte[] b):

Если длина b равна нулю, то никакие байты не читаются и 0 возвращается ;в противном случае предпринимается попытка прочитать хотя бы один байт.Если байт недоступен, поскольку поток находится в конце файла, возвращается значение -1 ;в противном случае, по крайней мере, один байт считывается и сохраняется в b.

Таким образом, в основном, когда вы используете while ((len = in.read(b)) > 0), вы выходите из цикла, если read() возвращает 0 (это означает, что длинапоследний прочитанный байт равен 0), хотя конец потока еще не достигнут и, таким образом, еще есть данные для чтения (поток не завершен).

0 голосов
/ 11 сентября 2018

Вы полностью меняете правило условия. Первый оператор проверяет значение точно на предмет не совпадения с -1, поэтому ваше новое условие должно соответствовать требованиям, что значение находится в диапазоне (-infinity, -1) и (-1, бесконечность)

(-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, если достигнут конец потока.

Ситуация описана здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...