Что возвращает 0 из InputStream.read()? Как справиться с этим?
Что означает 0 (количество прочитанных байтов), возвращаемое InputStream.read
? Как справиться с этой ситуацией?
Обновление: Я имею в виду методы read(byte[] b)
или read(byte[] b, int off, int len)
, которые возвращают количество прочитанных байтов.
Ответы
Ответ 1
Единственная ситуация, в которой a InputStream
может возвращать 0
из вызова read(byte[])
, когда прошло byte[]
in имеет длину 0:
byte[] buf = new byte[0];
int read = in.read(buf); // read will contain 0
Как указано в этой части JavaDoc:
Если длина b равна нулю, тогда никакие байты не читаются и возвращается 0
Мое предположение: вы использовали available()
, чтобы увидеть, насколько велик буфер, и он вернул 0
. Обратите внимание, что это неправильное использование available()
. JavaDoc явно заявляет, что:
Неправильно использовать возвращаемое значение этого метода для выделения буфера, предназначенного для хранения всех данных в этом потоке.
Ответ 2
Взгляните на реализацию javax.sound.AudioInputStream # read (byte [] b, int off, int len)... yuck. Они полностью нарушили стандартную семантику java.io.InputStream и вернули размер чтения 0, если вы запрашиваете меньше, чем весь кадр данных.
Так, к сожалению; общий совет (и api spec) должен исключать необходимость иметь дело с возвратом нуля при len > 0, но даже для классов JDK, которые вы не можете повсеместно полагаться на это, истинно для InputStreams произвольных типов.
Опять же, yuck.
Ответ 3
В соответствии с Java API Doc:
http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html#read(byte[])
Это может произойти только в том случае, если байт [], который вы передали, имеет нулевые элементы (новый байт [0]).
В других ситуациях он должен возвращать хотя бы один байт. Или -1, если EOF достиг. Или исключение.
Конечно: зависит от фактической реализации используемого InputStream!!! (это может быть неверно)
Ответ 4
Я наблюдал такое же поведение (чтение 0 байт), когда я создавал окно вывода консоли Swing и делал read-thread для stdout и stderr с помощью следующего кода:
this.pi = new PipedInputStream();
po = new PipedOutputStream((PipedInputStream)pi);
System.setOut(new PrintStream(po, true));
Когда "основное" приложение swing выходит, а окно консоли все еще открыто, я читаю 0 из этого .pi.read().
Чтение данных было помещено в окно консоли, в результате чего состояние гонки было каким-то образом, просто проигнорировав результат и не обновляя консольное окно, решена проблема.