Чем java.io.Buffer * stream отличается от обычных потоков? - PullRequest
11 голосов
/ 12 ноября 2009

1) Как буферизованные потоки работают в фоновом режиме, чем они отличаются от обычных потоков и каковы преимущества их использования?

2) DataInputStream также основано Байт . Но у него есть методы для readLine(). Какой здесь смысл?

Ответы [ 5 ]

8 голосов
/ 12 ноября 2009

Буферизованные Readers / Writers / InputStreams / OutputStreams читают и записывают в ОС большими кусками для оптимизации. В случае записывающих и выводящих потоков данные буферизуются в памяти до тех пор, пока их не будет достаточно, чтобы выписать большой кусок. В случае считывателей и входных потоков большой кусок читается с диска / сети / ... в буфер, и все чтения выполняются из этого буфера до тех пор, пока буфер не опустеет, а новый кусок не будет считан.

DataInputStream действительно основан на байтах. Метод readLine устарел. Внутренне он читает байты с диска / сети / ... побайтно, пока не соберет полную строку. Таким образом, этот поток можно ускорить, используя BufferedInputStream в качестве его источника, так что байты строки читаются из буфера в памяти, а не непосредственно с диска.

8 голосов
/ 12 ноября 2009

Из Javadoc BufferedInputStream:

BufferedInputStream добавляет функциональность к другому входному потоку, а именно, возможность буферизовать ввод и поддерживать методы меток и сброса. При создании BufferedInputStream создается внутренний буферный массив. Поскольку байты из потока считываются или пропускаются, внутренний буфер пополняется по мере необходимости из содержащегося входного потока, много байтов за раз. Операция пометки запоминает точку во входном потоке, а операция сброса вызывает считывание всех байтов, поскольку самая последняя операция пометки перечитывается до того, как новые байты извлекаются из содержащегося входного потока.

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

Тогда для BufferedOutputStream верно обратное.

mark () и reset () можно использовать следующим образом:

1 BufferedInputStream bis = new BufferedInputStream(is);
2 byte[] b = new byte[4];
3 bis.read(b); // read 4 bytes into b
4 bis.mark(10); // mark the stream at the current position - we can read 10 bytes before the mark point becomes invalid
5 bis.read(b); // read another 4 bytes into b
6 bis.reset(); // resets the position in the stream back to when mark was called
7 bis.read(b); // re-read the same 4 bytes as line 5 into b

Чтобы объяснить пометку / сбросить еще ...

BufferInputStream внутренне запоминает текущую позицию в буфере. По мере чтения байтов позиция будет увеличиваться. Вызов на отметку (10) сохранит текущую позицию. Последующие вызовы для чтения будут продолжать увеличивать текущую позицию, но вызов для сброса вернет текущую позицию к ее значению при вызове метки.

Аргумент для метки указывает, сколько байтов вы можете прочитать после вызова метки до того, как позиция метки станет недействительной. После того, как позиция метки признана недействительной, вы больше не можете вызвать сброс, чтобы вернуться к ней.

Например, если mark (2) был использован в строке 4 выше, IOException выдается, когда reset () вызывается в строке 6, поскольку позиция метки была бы недействительной, так как мы прочитали более 2 байтов.

4 голосов
/ 12 ноября 2009

При небуферизованном вводе-выводе каждый запрос на чтение или запись передается непосредственно в операционную систему. Буферизованные потоки ввода / вывода Java считывают и записывают данные в свой собственный буфер памяти (обычно это байтовый массив). Вызовы операционной системы выполняются только в том случае, если буфер пуст (при выполнении чтения) или буфер заполнен (при выполнении записи). Иногда рекомендуется очищать буфер вручную после критических точек в приложении.

Поскольку вызовы API операционной системы могут привести к доступу к диску, сетевой активности и т. П., Это может быть довольно дорогим. Использование буферов для пакетного ввода-вывода операционной системы в более крупные блоки часто значительно повышает производительность.

2 голосов
/ 12 ноября 2009

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

С java.io.BufferedOutputStream Javadocs:

Установив такой выходной поток, приложение может записать байты в основной выходной поток без обязательно вызывает вызов базовая система для каждого байта записано.

0 голосов
/ 12 июня 2013

Чтобы уменьшить этот вид издержек, платформа Java реализует буферизованные потоки ввода / вывода. Буферизованные входные потоки считывают данные из области памяти, известной как буфер; родной API ввода вызывается только тогда, когда буфер пуст. Аналогично, буферизованные выходные потоки записывают данные в буфер, а собственный API вывода вызывается только тогда, когда буфер заполнен.

...