Как java.Ио.Buffer * stream отличается от обычных потоков?

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

2) DataInputStream тоже байт на основе. Но методы readLine(). Какой в этом смысл?

5 ответов


из javadoc BufferedInputStream:

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

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

наоборот для 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 внутренне запоминает текущую позицию в буфере. По мере чтения байтов позиция будет увеличиваться. Вызов mark (10) сохранит текущую позицию. Последующие вызовы read будут продолжать увеличивать текущую позицию, но вызов reset вернет текущую позицию к ее значению, когда Марк был называемый.

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

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


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

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


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

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


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

с Ява.Ио.BufferedOutputStreamс документацией javadoc:

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


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