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

0

 

   Классы Pushback, поддерживающие обратный буфер (pushback buffer), наделены способностью возвращать (unread) считанные символы или байты назад в поток,    если    процесс   чтения    "зашел"    слишком    далеко.    Средства   классов Pushback обычно  находят  применение  при необходимости  разбиения  потока ввода (чтения) на отдельные лексемы. Например, программы лексического анализа часто обнаруживают конец очередной лексемы (скажем, идентификатора; только после ввода первого символа следующей лексемы. "Увидев" этот символ, анализатор обязан возвратить его в поток ввода, чтобы затем тот был корректн обработан при считывании следующей лексемы.  Рассмотрим пример,  которы демонстрирует  использование   объекта   PushbacklnputStream  для   поиска  во входном байтовом потоке самой длинной непрерывной последовательности од наковых байтов:

 

import java.io.*;

class SequenceCount {

   public  static void main(String[]   args)

 

throws  lOException

{

PushbacklnputStream

       in = new PushbacklnputStreamCSystem.in);

int max = 0;          // наибольшая длина найденной последовательности

int maxB = -1;      // Значение байта в найденной последовательности

int b;                     // Значение текущего байта

 

 

 

 do {

      int cnt;

int b1 = in.read();     // 1-й байт в последовательности

 for cnt = 1; (b = in.read()) = = bl; cnt++)

    continue;

if (cnt > max) {

max = cnt;                 // Сохранить значение длины  последовательности

max B= b1;               //  Сохранить значение байта

   }

    in.unread(b);         // возвратить байт в поток

 

  } while (b != -1);    // пока не достигнут конец потока

System.out.println(max + " байтов вида " + mахB);

  }

}

Мы можем узнать о достижении конца последовательности одинаковых байтов только в том случае, когда введем из потока очередной байт, который не удовлетворяет проверяемому условию. Этот байт с помощью метода unread возвращается в поток и будет считан в начале следующей итерации цикла do.

  В обоих классах, PushbacklnputStream и PushbackReader, поддерживаются два конструктора: один в качестве параметров принимает ссылку на объект "внутреннего" потока и значение объема буфера, а другому передается только ссылка на объект потока — размер буфера, равный одной наименьшей порции Данных (байту или символу), предлагается по умолчанию. Попытка возврата в поток более длинной последовательности данных, нежели та, которую в состоянии принять буфер, приводит к выбрасыванию исключения типа lOException.

  В каждом классе Pushback определены три варианта метода unread, которые соответствуют перегруженным версиям метода read. Ниже мы рассмотрим методы unread только символьной разновидности потоков Pushback, PushbackReader, поскольку методы байтового потока, PushbacklnputStream, аналогичны по синтаксису и назначению.

 

 Public void unread(int с)  throws lOException

Возвращает в поток чтения единственный символ С. Если обратный буфер потока заполнен, выбрасывается исключение типа lOException.

Public void unread(char[]   buf,   int offset,   int count)

    throws lOException

Возвращает в поток чтения символы из части массива buf, начиная с символа buf[offset] и вплоть до символа buf[offset+count-l]. Возвращенные символы сохраняются в начале обратного буфера потока: первым символом,   подлежащим   чтению   при   выполнении   очередной   операции read,      окажется     символ     buf [offset],      за     ним    будет     считан buf [off set+1] и т.д. Если для сохранения возвращаемой порции симво лов свободной емкости буфера не достаточно, выбрасывается исключение типа IOException.

public void unread(char[]   buf)  throws IOException

     Метод     аналогичен     предыдущему     при     условии   unread(buf,  0,  buf.length).

   Пусть, например, посредством двух последовательных вызовов unread в поток возвращаются символы ‘ 1′ и ‘ 2 ‘; тогда считаны они будут в таком порядке: ‘2’, а затем ‘1’, — поскольку символ ‘2’ был возвращен последним. При каждом обращении к unread в обратном буфере сохраняется определенная частная последовательность символов, так что при выполнении кода

pbr.unread(new char[]   {‘I’,   ‘2’});    

pbr.unread(new char[]   {‘3′,   ‘4’});        

for  (int i  = 0;   i  < 4;   i++)

    System.out.println(i  + ":   " + (char)pbr. Read()) ;

будет получен следующий результат:

0:  3

1:  4

2:  1

3:  2

Данные, возвращенные в буфер последней операцией unread (т.е. пара символов 1 3′ и ‘4’), будут считаны из буфера первыми; при этом очередность следования символов внутри порции данных сохраняется. По завершении ввода данных одной последовательности считываются символы из набора, возвращенного в буфер предыдущей инструкцией unread, и т.д. Метод unread возвращает в буфер копию данных, так что изменения, внесенные в них после обращения к unread, не скажутся на результате последующего выполнения read.

 

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

По теме:

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