Вызов read
работает, как задумано; вы просто не понимаете, как он устроен (что, правда, немного странно).
Метод read(byteArray)
гарантированно считывает не менее 1 байта; он не будет читать ничего, только если возникнет исключение или поток будет закрыт.
Однако не гарантируется заполнение предоставленного байтового массива. Для него вполне нормально читать только 1 байт (spe c говорит, что это нормально, поэтому ваш код должен быть написан, чтобы справиться с этим). Даже если есть еще что отправить.
Итак, сколько байтов вы на самом деле получите? ¯_ (ツ) _ / ¯ Зависит от вашей сетевой карты, ОС, виртуальной машины и фазы луны.
Следовательно, «одиночный» вызов чтения, подобный этому, всегда является ошибкой. Это должно происходить в некотором роде l oop.
К счастью, вам не нужно ничего программировать, если вы не используете довольно старую версию Java; в наши дни тип InputStream
имеет метод readNBytes
, который гарантирует, что он заполнит весь предоставленный байтовый массив, предоставляя вам меньше байтов, только если происходит исключение или если поток заканчивается до полного Массив байтов заполнен.
Итак, вместо: in.read(buffer)
, правильный вызов: in.readNBytes(buffer, 0, buffer.length)
.
Примечание: конструкция read
похожа на это, потому что она связана с тем, как I / O фактически работает: я могу дать вам 2016 байтов прямо сейчас; если вы хотите больше, это займет больше времени (еще один обход карты или, возможно, ожидание, пока IP-пакеты проберутся через океан, кто знает, сколько времени это может занять); и часто вы не можете знать, что размер magi c позволяет создать ваш байтовый массив, чтобы вы могли получить максимально быстрый ответ, не делая слишком много запросов к read()
, что также будет медленным - таким образом, вы можете не решить эту дилемму, сказав: «Ну, просто дайте небольшой массив байтов, если вы хотите быстрых ответов!». Теперь вы знаете, почему это так:)