Чтение онлайн

на главную

Жанры

Программирование на Java

Вязовик Н.А.

Шрифт:

Задачи, возникающие при вводе/выводе весьма разнообразны - это может быть считывание байтов из файлов, объектов из файлов, объектов из массивов, буферизованное считывание строк из массивов и т.д. В такой ситуации решение с использованием простого наследования приводит к возникновению слишком большого числа подклассов. Более эффективно применение надстроек (в ООП этот шаблон называется адаптер) Надстройки – наложение дополнительных объектов для получения новых свойств и функций. Таким образом, необходимо создать несколько дополнительных объектов – адаптеров к классам ввода/вывода. В java.io их еще называют фильтрами. При

этом надстройка-фильтр включает в себя интерфейс объекта, на который надстраивается, поэтому может быть, в свою очередь, дополнительно надстроена.

В java.io интерфейс для таких надстроек ввода/вывода предоставляют классы FilterInputStream (для входных потоков ) и FilterOutputStream (для выходных потоков ). Эти классы унаследованы от основных базовых классов ввода/вывода – InputStream и OutputStream, соответственно. Конструктор FilterInputStream принимает в качестве параметра объект InputStream и имеет модификатор доступа protected.

Классы FilterI/OStream являются базовыми для надстроек и определяют общий интерфейс для надстраиваемых объектов. Потоки-надстройки не являются источниками данных. Они лишь модифицируют (расширяют) работу надстраиваемого потока.

BufferedInputStream и BufferedOutputStream

На практике при считывании с внешних устройств ввод данных почти всегда необходимо буферизировать. Для буферизации данных служат классы BufferedInputStream и BufferedOutputStream.

BufferedInputStream содержит массив байт, который служит буфером для считываемых данных. То есть когда байты из потока считываются либо пропускаются (метод skip ), сначала заполняется буферный массив, причем, из надстраиваемого потока загружается сразу много байт, чтобы не требовалось обращаться к нему при каждой операции read или skip. Также класс BufferedInputStream добавляет поддержку методов mark и reset. Эти методы определены еще в классе InputStream, но там их реализация по умолчанию бросает исключение IOException. Метод mark запоминает точку во входном потоке, а вызов метода reset приводит к тому, что все байты, полученные после последнего вызова mark, будут считываться повторно, прежде, чем новые байты начнут поступать из надстроенного входного потока.

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

Следующий пример наглядно демонстрирует повышение скорости считывания данных из файла с использованием буфера:

try {

String fileName = "d:\\file1";

InputStream inStream = null;

OutputStream outStream = null;

//Записать в файл некоторое количество байт

long timeStart = System.currentTimeMillis;

outStream = new FileOutputStream(fileName);

outStream = new BufferedOutputStream(outStream);

for(int i=1000000; --i>=0;) {

outStream.write(i);

}

long time = System.currentTimeMillis - timeStart;

System.out.println("Writing time: " + time + " millisec");

outStream.close;

//

Определить время считывания без буферизации

timeStart = System.currentTimeMillis;

inStream = new FileInputStream(fileName);

while(inStream.read!=-1) {

}

time = System.currentTimeMillis - timeStart; inStream.close;

System.out.println("Direct read time: " + (time) + " millisec");

// Теперь применим буферизацию

timeStart = System.currentTimeMillis;

inStream = new FileInputStream(fileName);

inStream = new BufferedInputStream(inStream);

while(inStream.read!=-1) {

}

time = System.currentTimeMillis - timeStart; inStream.close;

System.out.println("Buffered read time: " + (time) + " millisec");

}

catch (IOException e) {

System.out.println("IOException: " + e.toString);

e.printStackTrace;

}

Пример 15.7.

Результатом могут быть, например, такие значения:

Writing time: 359 millisec

Direct read time: 6546 millisec

Buffered read time: 250 millisec

Пример 15.8.

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

Классы BufferedI/OStream добавляют только внутреннюю логику обработки запросов, но не добавляют никаких новых методов. Следующие два фильтра предоставляют некоторые дополнительные возможности для работы с потоками.

LineNumberInputStream

Класс LineNumberInputStream во время чтения данных производит подсчет, сколько строк было считано из потока. Номер строки, на которой в данный момент происходит чтение, можно узнать путем вызова метода getLineNumber. Также можно и перейти к определенной строке вызовом метода setLineNumber(int lineNumber).

Под строкой при этом понимается набор байт, оканчивающийся либо '\n', либо '\r', либо их комбинацией '\r\n', именно в этой последовательности.

Аналогичный класс для исходящего потока отсутствует. LineNumberInputStream, начиная с версии 1.1, объявлен deprecated, то есть использовать его не рекомендуется. Его заменил класс LineNumberReader (рассматривается ниже), принцип работы которого точно такой же.

PushBackInputStream

Этот фильтр позволяет вернуть во входной поток считанные из него данные. Такое действие производится вызовом метода unread. Понятно, что обеспечивается подобная функциональность за счет наличия в классе специального буфера – массива байт, который хранит считанную информацию. Если будет произведен откат (вызван метод unread ), то во время следующего считывания эти данные будут выдаваться еще раз как только полученные. При создании объекта можно указать размер буфера.

Поделиться:
Популярные книги

Ученичество. Книга 2

Понарошку Евгений
2. Государственный маг
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ученичество. Книга 2

Император поневоле

Распопов Дмитрий Викторович
6. Фараон
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Император поневоле

Лорд Системы 7

Токсик Саша
7. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 7

Целитель. Книга вторая

Первухин Андрей Евгеньевич
2. Целитель
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Целитель. Книга вторая

Темный Патриарх Светлого Рода 3

Лисицин Евгений
3. Темный Патриарх Светлого Рода
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 3

Случайная свадьба (+ Бонус)

Тоцка Тала
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Случайная свадьба (+ Бонус)

Прометей: каменный век II

Рави Ивар
2. Прометей
Фантастика:
альтернативная история
7.40
рейтинг книги
Прометей: каменный век II

Жребий некроманта. Надежда рода

Решетов Евгений Валерьевич
1. Жребий некроманта
Фантастика:
фэнтези
попаданцы
6.50
рейтинг книги
Жребий некроманта. Надежда рода

Возвышение Меркурия

Кронос Александр
1. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия

Не грози Дубровскому! Том Х

Панарин Антон
10. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том Х

Идеальный мир для Лекаря 12

Сапфир Олег
12. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 12

Хочу тебя навсегда

Джокер Ольга
2. Люби меня
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Хочу тебя навсегда

СД. Том 15

Клеванский Кирилл Сергеевич
15. Сердце дракона
Фантастика:
героическая фантастика
боевая фантастика
6.14
рейтинг книги
СД. Том 15

Смерть может танцевать 3

Вальтер Макс
3. Безликий
Фантастика:
боевая фантастика
5.40
рейтинг книги
Смерть может танцевать 3