Как java.io. Буфер* поток отличается от нормальных потоков?

Вы рассмотрели использование типа данных money для хранения сумм в долларах?

Относительно Довода "против", что десятичное число поднимает еще один байт, я сказал бы, не заботятся об этом. В 1 миллионе строк Вы будете только использовать еще 1 МБ, и устройство хранения данных является очень дешевым в эти дни.

11
задан AnV 18 August 2016 в 11:27
поделиться

4 ответа

Из 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

Чтобы объяснить mark / reset some more ...

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

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

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

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

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

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

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

8
ответ дан 3 December 2019 в 05:13
поделиться

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

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

8
ответ дан 3 December 2019 в 05:13
поделиться

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

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

4
ответ дан 3 December 2019 в 05:13
поделиться

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

Из документации Javadocs java.io.BufferedOutputStream :

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

2
ответ дан 3 December 2019 в 05:13
поделиться
Другие вопросы по тегам:

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