Главная » Java » Потоки Buffered в Java

0

 

   Классы семейства буферизованных потоков (buffered streams) Buffered

BufferedlnputStream, BufferedOutputStream, BufferedReader и BufferedWriter— осуществляют буферизацию данных, позволяющую избежать необходимости обращения к источнику (получателю) данных при выполнении каждой отдельной операции read или write. Эти классы часто используются в сочетании с потоками семейства Fi Те — доступ к данным на диске выполняется намного медленнее, нежели к информации в буфере памяти, и средства буферизации помогают снизить потребность в обращениях к диску.

   В каждом из потоков Buffered поддерживаются два конструктора: один в качестве параметров принимает ссылку на объект "внутреннего" потока и значение объема буфера, а другому передается только ссылка на объект потока — размер буфера предлагается по умолчанию.

   Когда метод read потока Buffered, вызываемый для ввода (чтения) данных, обнаруживает, что буфер потока пуст, он вызывает одноименный метод потока-источника, заполняет буфер настолько большой порцией данных, насколько это возможно (выполняя блокировку только в том случае, если необходимо дождаться появления данных), и возвращает запрошенные данные из буфера. При очередных обращениях к методу read объекта Buffered данные будут извлекаться из буфера, пока его содержимое не исчерпается, и в этот момент объекту вновь придется вызвать read потока-источника. Процесс повторяется до тех пор, пока не иссякнет источник данных.

   Buffered-потоки вывода (записи) ведут себя аналогичным образом. Когда wri te заполняет буфер данных, вызывается одноименный метод потока-получателя, освобождающий буфер. Такой механизм буферизации помогает превратить последовательность запросов на вывод (запись) небольших порций данных, адресуемых объекту Buffered, в единственный вызов метода write потока-получателя.

   Вот как можно построить байтовый буферизованный поток вывода данны в файл:

 

   new BufferedOutputStreamCnew FileOutputStream(path));

 

Мы создаем объект класса FileOutputStream, передавая его конструктору аргумент-строку, задающую путь к файлу, и на основе объекта FileOutputStream строим новый экземпляр класса BufferedOutputStream — буферизованный поток готов к применению. Подобная схема позволяет осуществлять буферизацию байтовых данных, выводимых в файл.

   Если позже вы намереваетесь напрямую обращаться к методам "внутреннего" потока, выполняющего роль источника или получателя данных (в нашем примере это объект FileOutputStream), необходимо загодя позаботиться о сохранении ссылки на такой объект, поскольку способов получения ее с помощью объекта "внешнего", фильтрованного, потока (такого как BufferedOutputStream) не существует. Впрочем, необходимость непосредственных манипуляций с "внутренним" потоком возникает весьма редко. Сохраняя ссылку на такой поток и обращаясь к нему, вы должны предварительно выполнять операции сброса (flush) "внешнего" потока вывода (записи), поскольку тот может содержать буферизованные данные, еще не переданные "внутреннему" потоку. При закрытии "внешнего" потока закрываются и "внутренние" потоки всех уровней подчиненности, так что сохраненные ссылки на них утратят свою действенность.

  Символьные потоки Buffered способны обращаться и со строками текста. Метод newLine класса BufferedWriter записывает в поток признак завершения строки. В каждой системе содержимое признака завершения строки, которое не обязательно должно ограничиваться единственным символом, задается по-разному; для этого используется одно из системных свойств (system properties) типа String, line.separator (см. раздел 18.1.2 на странице 496). Обращаться к методу newLine для разграничения строк в текстовом файле следует, в частности, тогда, когда файл может быть открыт пользователем для визуального просмотра.

  Метод readLine класса BufferedReader возвращает строку текста, считанную из потока, в виде объекта String. Метод способен распознавать разделители строк любого вида: перевод строки (line feed) (\n), возврат каретки (carriage return) (\r) либо символ возврата каретки, сопровождаемый признаком перевода строки (\г\п). При этом предполагается, что вы не пользовались свойством line.separator для определения иного признака завершения строки. В противном случае корректность распознавания методом readLine строк, разграниченных посредством newLi ne, не гарантируется. В строку, возвращаемую методом readLine, разделитель не включается. Если в процессе считывания признак конца потока встречается раньше признака завершения строки, readLine возвращает значение null.

 

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии