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

0

 

  Классы семейства фильтрованных потоков (filtered streams) Filter-

FilterlnputStream, FilterOutputStream, FilterReader и Filterwriter -_

позволяют объединять потоки в цепочки для получения составных потоков, об

ладающих расширенным набором функций. Каждый фильтрованный поток дан-

ных привязывается к другому потоку, которому передает полномочия по факти

ческому выполнению операций ввода или вывода. Мощь потоков Filter обу

словлена способностью к фильтрации — в более широком смысле, обработке    

данных, подлежащих вводу (чтению) или выводу (записи).

   Байтовые потоки Filter обладают дополнительными конструкторами, получающими в качестве параметров ссылки на объекты потоков данных соответствующего типа inputStream или OutputStream, которые обеспечивают ввод или вывод. Аналогично, в составе символьных потоков Fi I ter предусмотрены конструкторы, которым передаются ссылки на объекты потоков Reader или Writer, выполняющих чтение или запись данных. Впрочем, многие классы символьных потоков сами по себе обладают конструкторами, принимающими в виде параметров ссылки на объекты других символьных потоков, так что классы, производные от Reader и Writer, способны действовать как фильтры даже тогда, когда они не являются прямыми наследниками классов FilterReader или Filterwriter.

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

 

public class uppercaseconvertor extends  FilterReader {

     public uppercaseConvertor(Reader in)  {

          super(in);

      }

public int read () throws iOException {

int с = super. Read() ;

return (c == -1 ? с : character.toupperCase((char)c));

}

public int  read(char[]   buf,   int offset,   int count)

   throws IOException

{

  int nread = super.read(buf,   offset,   count);

  int last = offset + nread;

  for  (int i  = offset;   i   < last;   i++)

      buf[i]  = Character.touppercase(buf[i]);

 return nread;

}

Мы переопределили каждый из вариантов метода read с целью осуществлен операции чтения с дальнейшим преобразованием символов результата к вер му регистру. Чтение фактически выполняется с помощью обращения к соот ствующим версиям read базового класса FilterReader. Обратите внимание, чт^ вызов методов read объекта i n не выполняется — это привело бы к отказу средств фильтрации, предоставляемых базовым классом. Кроме того, примит   ^ сведению, что мы обязаны отслеживать момент достижения конца потока, использовании версии  read без аргументов должна осуществляться явная проверка этого события, но в случае обращения к варианту read, обеспечивающему чтение символов в массив, возвращенное значение, равное -1, просто воспрепятствует выполнению тела цикла for. В последнем случае следует также тщательно следить за тем, чтобы к верхнему регистру преобразовывались только те символы, которые сохранены в предоставленном для этого буфере.

Применить созданный класс-конвертор можно было бы следующим образом:

public  static void main(String[]   args)

    throws IOException

{

StringReader src = new StringReader(args[O]);

FilterReader f = new uppercaseConvertor(src);

 int c;

while  ((c = f.readO)   != -1)

 System.out.print((char)c);

 System.out.println();

}

В качестве источника данных используется объект потокового класса StringReader, осуществляющий чтение символов из строки (см. раздел 15.4.7 на странице 393), который в качестве параметра передается объекту-оболочке созданного нами типа Uppercaseconvertor. При чтении символов из фильтрованного потока все соответствующие символы потока строки подвергаются преобразованию к верхнему регистру. Задав в качестве параметра командной строки последовательность символов "подлежит преобразованию к верхнему регистру", в результате мы получим:

 

   ПОДЛЕЖИТ  ПРЕОБРАЗОВАНИЮ  К   ВЕРХНЕМУ  РЕГИСТРУ

 

  Позволяется связывать в единую цепочку любое количество байтовых (символьных)

Filter-потоков ввода (чтения). Источником исходных данных может быть поток, не относящийся к семейству потоков Filter. Байтовый поток ввода нетрудно преобразовать в символьный поток чтения с помощью объекта класса inputStreamReader (см. раздел 15.3).

  Подобным образом могут соединяться в цепочки и FiIter-потоки вывода (записи), так что данные, выводимые (записываемые) в один поток, будут отфильтрованы и переданы следующему потоку. Все потоки вывода (записи) в цепочке, начиная с первого и заканчивая предпоследним, должны относиться к классу FiIte, но последним может быть объект любого потокового класса вывода (записи). Для преобразования символьного потока записи в байтовый поток вывода можно воспользоваться объектом класса OutputStreamWriter (см. раз-Дел 15.3).

Не все классы семейства Filter в действительности осуществляют изменение

иных. Некоторые просто привносят дополнительные черты поведения, как в

случае с буферизованными потоками, рассматриваемыми в следующем разделе, а

другие  предлагают новые  интерфейсы  взаимодействия  с  потоками  (например,

ассы типа Print). Все эти классы относятся к семейству Filter и их объекты

могут принимать участие в составлении цепочек фильтрации.

 

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

По теме:

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