2015-11-04 2 views
0

Как гласит название, может DataInputStream.read() переопределить ранее прочитанные байты, если имеется больше байтов, чем размер буфера, если в первом чтении были пропущены некоторые байты?Будет ли DataInputStream переопределять байты с последовательными чтениями

Есть пакеты фиксированного размера, обмен которыми осуществляется между одноранговыми узлами, и возможно, что два пакета доступны в гнезде. Предположим, что размер одного пакета равен 500, и в соке есть два пакета общего размера 1000. Кроме того, допустим, что для чтения получает 400 байт из доступного 1000.

  • Даже возможно, что read() не читает все 500 байт, если они доступны?

  • Что произойдет, если чтение будет вызвано снова, возможно ли, что прочитано более 100 байтов?

Это не совсем ясно мне, что происходит в этом случае с учетом Javadoc:

Первый прочитанный байт сохраняется в элементе Ь [0], следующий в Ь [1] , и так далее. Количество прочитанных байтов, самое большее, равно длине b.

Я хотел бы знать, если ниже блок кода должен быть изменен, как показано в комментарии, чтобы полностью прочитать только один пакет.

while ((readBytes = stream.read(buffer)) != -1) { 

     totalBytes += readBytes; 

     if (totalBytes < buffer.length) { // must this be != instead of < ? 

      continue; 
     } 

     // all bytes are available 
     else { 

      break; 
     } 
+0

Ваш пример неясен - вы говорите об одном пакете размером 500 и двух пакетах размером 1000, всего в двух пакетах. –

+0

Я имею в виду, что перед чтением доступно 1000 байт. Буфер имеет размер 500, и я хотел бы читать только 500, принадлежащих первому пакету. Buffer is byte [] передан методу чтения. – John

+0

Я даже не уверен, возможна ли такая ситуация. Так как мне не ясно, будет ли я читать все байты, доступные в момент чтения. – John

ответ

1

Каждый раз, когда вы звоните read(byte[]), он будет:

  • Block до по крайней мере один байт не считывается со входа, или вход закрыт
  • Копировать байты из ввода в массив , начиная с индекса 0 массива
  • Возврат, когда больше нет доступных байтов (как правило, в любом случае - может быть некоторая задержка, когда он ждет некоторое время, чтобы больше стало доступным)

Нет памяти о предыдущих read вызовах - он не начнет записывать в массив по предыдущему индексу. Если вы хотите, что поведение, вы должны написать его самостоятельно:

byte[] buffer = new byte[500]; 
int totalRead = 0; 
while (totalRead < buffer.length) { 
    // Pass in an offset and length, so we can keep reading into the 
    // next part of the array. 
    int bytesRead = input.read(buffer, totalRead, buffer.length - totalRead); 
    if (bytesRead == -1) { 
     throw new EOFException(); // Or whatever... stream ended early 
    } 
    totalRead += bytesRead; 
} 

... или звоните readFully(), которые в основном будут делать то же самое.

+0

«Нет памяти о предыдущих читаемых звонках» большое спасибо :) – John

+0

Он не будет блокировать дважды. – EJP

+0

@EJP: Разве это не так, как в основной реализации «InputStream»? Было бы вполне возможно написать поток на основе сокетов, который блокировал бы (скажем) дополнительные 100 мс, если он недавно получил пакет, но недостаточно для удовлетворения запрошенной информации о чтении? –