В настоящее время я полагаюсь на метод ObjectInputStream.available()
, чтобы рассказать мне, сколько байтов осталось в потоке. Причина для этого - я пишу некоторые тесты единицы/интеграции для некоторых функций, которые обрабатывают потоки, и я просто пытаюсь обеспечить, чтобы метод available()
возвращал 0 после того, как я закончил.Лучший способ узнать, сколько байтов в потоке?
К сожалению, при тестировании на отказ (т. Е. Я отправил около 8 байтов вниз по потоку) мое утверждение для available() == 0
подходит к истине, когда оно должно быть ложным. Он должен показывать> 0 или 8 байтов!
Я знаю, что метод available()
классически ненадежен, но я решил, что он покажет что-то как минимум> 0!
Есть ли более надежный способ проверки, является ли поток пустым или нет (в конце концов, моя главная цель здесь)? Возможно, в домене Apache IO или в какой-то другой библиотеке?
Кто-нибудь знает, почему метод available()
настолько глубоко ненадежен; в чем смысл? Или есть конкретный, правильный способ его использования?
Update:
Так как многие из вас могут читать комментарии, главный вопрос, я столкнулся в том, что на одном конце потока, я посылаю определенное количество байтов но с другой стороны, не все байты прибывают!
В частности, я посылаю 205498 байт на одном конце и получаю только 204988 на другом, последовательно. Я контролирую обе стороны этой операции между потоками в сокете, но это должно быть неважно.
Вот код, который я написал для сбора всех байтов.
public static int copyStream(InputStream readFrom, OutputStream writeTo, int bytesToRead)
throws IOException {
int bytesReadTotal = 0, bytesRead = 0, countTries = 0, available = 0, bufferSize = 1024 * 4;
byte[] buffer = new byte[bufferSize];
while (bytesReadTotal < bytesToRead) {
if (bytesToRead - bytesReadTotal < bufferSize)
buffer = new byte[bytesToRead - bytesReadTotal];
if (0 < (available = readFrom.available())) {
bytesReadTotal += (bytesRead = readFrom.read(buffer));
writeTo.write(buffer, 0, bytesRead);
countTries = 0;
} else if (countTries < 1000)
try {
countTries++;
Thread.sleep(1L);
} catch (InterruptedException ignore) {}
else
break;
}
return bytesReadTotal;
}
Я установил переменную countTries, чтобы увидеть, что произойдет. Даже без countTires, он будет блокироваться навсегда, пока не достигнет BytesToRead.
Что может заставить поток внезапно блокировать бесконечно так? Я знаю, что на другом конце он полностью отправляет байты (поскольку он фактически использует один и тот же метод, и я вижу, что он завершает функцию с полным байтовым соглашением bytesReadTotal в конце, но получатель этого не делает. Я смотрю на массивы, они идеально совпадают до до конца, а также.
UPDATE2
Я заметил, что когда я добавил writeTo.flush()
в конце моего метода copyStream, кажется, снова работать. Хм .. Почему эти ситуации очень важны в этой ситуации. Т.е. почему бы не использовать ее, чтобы поток был перма-блоком?
Как вы должны знать, что есть 'x' байт в потоке, не читая его? Метод 'Доступный()' явно указывает _Отбрасывает количество байтов, которые можно читать без блокировки. Если вам нужно было прочитать больше байтов, вам нужно будет заблокировать. –
Вы должны проверить с помощью 'InputStream # read()' return '-1', чтобы узнать, достигнут ли конец потока. –
@SotiriosDelimanolis, не должен 'available()' давать хотя бы возвращаемое значение 1, чтобы показать, что для блокировки есть хотя бы 1 байт? –