Я должен всегда переносить InputStream как BufferedInputStream?

Имеет смысл всегда переносить InputStream как BufferedInputStream, когда я знаю, является ли данный InputStream чем-то другим, чем буферизированный? Для, например:

InputStream is = API.getFromSomewhere()
if(!(is instanceof BufferedInputStream))
  return new BufferedInputStream(is);
return is;
40
задан geejay 3 June 2010 в 07:36
поделиться

4 ответа

Я бы не стал этого делать, я бы оставил это на максимально возможном уровне абстракции. Если вы не собираетесь использовать возможности метки и сброса BufferedStream, зачем его обертывать?

Если он нужен потребителю, лучше обернуть его туда.

6
ответ дан 27 November 2019 в 01:53
поделиться

Имеет ли смысл always обернуть InputStream как BufferedInputStream, когда я знаю, является ли данный InputStream чем-то иным, чем буферизованный?

Нет.

Это имеет смысл, если вы, вероятно, будете выполнять много небольших считывания (один байт или несколько байтов за раз) или если вы хотите использовать некоторые функции более высокого уровня, предлагаемые буферизованными API; например, метод BufferedReader.readLine().

Однако, если вы собираетесь выполнять чтение больших блоков только с помощью методов read(byte[]) и / или read(byte[], int, int), обертывание InputStream в BufferedInputStream не поможет.

(В ответ на комментарий @Peter Тиллмана к его собственному ответу, блок чтения вариантов использования определенно составляет более 0,1% использования классов InputStream!! Однакоон прав в том смысле, что обычно безвредно использовать буферизованный API, когда вам это не нужно.)

34
ответ дан 27 November 2019 в 01:53
поделиться

Буферизация может потребоваться не всегда, поэтому ответом будет нет, в некоторых случаях это просто накладные расходы.

Есть еще одна причина, по которой это «Нет», и это может быть более серьезным. BufferedInputStream (или BufferedReader ) может вызывать непредсказуемые сбои при использовании с сетевым сокетом, если вы также включили тайм-аут для сокета. Тайм-аут может произойти при чтении пакета. Вы больше не сможете получить доступ к данным, которые были переданы в эту точку - даже если бы вы знали, что существует ненулевое количество байтов (см. java.net.SocketTimeoutException , который является подклассом java.io.InterruptedIOException , поэтому доступна переменная bytesTransferred ).

Если вам интересно, как может произойти тайм-аут сокета во время чтения, просто подумайте о вызове метода read (bytes []) , и исходный пакет, содержащий сообщение, оказался разделенным, но один из частичные пакеты задерживаются по истечении тайм-аута (или оставшейся части тайм-аута). Это может происходить чаще, если снова обернуть его во что-то, что реализует java.io.DataInput (любое чтение для нескольких байтовых значений, например readLong () или readFully () или метод BufferedReader.readLine () .

Обратите внимание, что java.io.DataInputStream также является плохим кандидатом для потоков сокетов, у которых есть тайм-аут, поскольку он не t хорошо себя ведет и с исключениями по таймауту.

2
ответ дан 27 November 2019 в 01:53
поделиться

Это также зависит от того, как вы собираетесь читать из InputStream. Если вы собираетесь читать его по символу / байту (например, read ()), тогда BufferedInputStream сократит ваши накладные расходы за счет очередного массового чтения от вашего имени. Если вы собираетесь читать его в массив размером 4 или 8 Кбайт / символ по блоку, то BuffredInputStream, вероятно, не принесет вам пользы.

0
ответ дан 27 November 2019 в 01:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: