Оглавление

Работа с файлами
Классы потоков
Стандартные потоки
Потоки и файлы
Запись и чтение потоков
Закрывание потоков
Сброс буферов
Потоки в памяти
Stream Tokenizer
String Tokenizer
Класс File
Произвольный доступ
Приложение StreamToken
Приложение DirectFile

    Приложение StreamToken

    В приложении StreamToken мы демонстрируем использование класса StreamTokenizer для разбора входного потока.

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

    pic04.gif (5983 bytes)

    Рис. 4. Разбор входного потока в приложении StreamToken

    Обратите внимание, что в процессе разбора значение 3.14 было воспринято как числовое, а 3,14 - нет. Это потому, что при настройке разборщика мы указали, что символ '.' является обычным.

    Исходный текст приложения

    Исходный текст приложения StreamToken представлен в листинге 1.

    Листинг 1. Файл StreamToken.java

    import java.io.*;
    public class StreamToken
    
    {
    
      public static void main(String args[])
    
      {
    
        DataOutputStream OutStream;
    
        DataInputStream  InStream;
        byte bKbdInput[] = new byte[256];
    
        String sOut;
        try
    
        {
    
          System.out.println(
    
            "Enter string to parse...");
          System.in.read(bKbdInput);
          sOut = new String(bKbdInput, 0); 
          OutStream = new DataOutputStream(
    
            new BufferedOutputStream(
    
              new FileOutputStream(
    
               "output.txt")));
          OutStream.writeBytes(sOut);
    
          OutStream.close();
          InStream = new DataInputStream(
    
            new BufferedInputStream(
    
              new FileInputStream(
    
                "output.txt")));
          TokenizerOfStream tos = 
    
            new TokenizerOfStream();
          tos.TokenizeIt(InStream);
    
          InStream.close();
          System.out.println(
    
            "Press <Enter> to terminate...");
    
          System.in.read(bKbdInput);
    
        }
    
        catch(Exception ioe)
    
        {
    
          System.out.println(ioe.toString());
    
        }
    
      }
    
    }
    class TokenizerOfStream
    
    {
    
      public void TokenizeIt(InputStream is)
    
      {
    
        StreamTokenizer stok;
    
        String str;
        try
    
        {
    
          stok = new StreamTokenizer(is);
    
          stok.slashSlashComments(true);
          stok.ordinaryChar('.');
          while(stok.nextToken() !=
    
             StreamTokenizer.TT_EOF)
    
          {
    
            switch(stok.ttype)
    
            {
    
              case StreamTokenizer.TT_WORD:
    
              {
    
                str = new String(
    
                  "\nTT_WORD >" + stok.sval);
    
                break;
    
              }
              case StreamTokenizer.TT_NUMBER:
    
              {
    
                str = "\nTT_NUMBER >" +
    
                   Double.toString(stok.nval);
    
                break;
    
              }
              case StreamTokenizer.TT_EOL:
    
              {
    
                str = new String("> End of line");
    
                break;
    
              }
              default:
    
                {
    
                  if((char)stok.ttype == '"')
    
                  {
    
                    str = new String(
    
                      "\nTT_WORD >" + stok.sval);
    
                  }
                  else
    
                    str = "> " + 
    
                      String.valueOf(
    
                        (char)stok.ttype);
    
                }
    
            }
            System.out.println(str);
    
          }
    
        }
    
        catch(Exception ioe)
    
        {
    
          System.out.println(ioe.toString());
    
        }
    
      }
    
    }

    Описание исходного текста приложения

    После ввода строки с клавиатуры и записи ее в файл через поток наше приложение создает входной буферизованный поток, как это показано ниже:

    InStream = new DataInputStream(
    
      new BufferedInputStream(
    
      new FileInputStream("output.txt")));

    Далее для этого потока создается разборщик, который оформлен в отдельном классе TokenizerOfStream, определенном в нашем приложении:

    TokenizerOfStream tos = 
    
      new TokenizerOfStream();

    Вслед за этим мы вызываем метод TokenizeIt, определенный в классе TokenizerOfStream, передавая ему в качестве параметра ссылку на входной поток:

    tos.TokenizeIt(InStream);

    Метод TokenizeIt выполняет разбор входного потока, отображая результаты разбора на консоли. После выполнения разбора входной поток закрывается методом close:

    InStream.close();

    Самое интересное в нашем приложении связано, очевидно, с классом TokenizerOfStream, поэтому перейдем к его описанию.

    В этом классе определен только один метод TokenizeIt:

    public void TokenizeIt(InputStream is)
    
    {
    
      . . .
    
    }

    Получая в качестве параметра ссылку на входной поток, он прежде всего создает для него разборщик класса StreamTokenizer:

    StreamTokenizer stok;
    
    stok = new StreamTokenizer(is);

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

    stok.slashSlashComments(true);
    
    stok.ordinaryChar('.');

    Метод slashSlashComments включает режим распознавания комментариев в стиле языка программирования С++, а метод ordinaryChar объявляет символ '.' обычным символом.

    После настройки запускается цикл разбора входного потока, причем условием завершения цикла является достижение конца этого потока:

    while(stok.nextToken() != 
    
      StreamTokenizer.TT_EOF)
    
    {
    
      . . .
    
    }

    В цикле анализируется содержимое поля ttype, которое зависит от типа элемента, обнаруженного во входном потоке:

    switch(stok.ttype)
    
    {
    
      case StreamTokenizer.TT_WORD:
    
      {
    
        str = new String("\nTT_WORD >"
    
           + stok.sval);
    
        break;
    
      }
    
      case StreamTokenizer.TT_NUMBER:
    
      {
    
        str = "\nTT_NUMBER >" + 
    
          Double.toString(stok.nval);
    
        break;
    
      }
    
      case StreamTokenizer.TT_EOL:
    
      {
    
        str = new String("> End of line");
    
        break;
    
      }
    
      default:
    
      {
    
        if((char)stok.ttype == '"')
    
          str = new String(
    
            "\nTT_WORD >" + stok.sval);
    
        else
    
          str = "> " + String.valueOf(
    
           (char)stok.ttype);
    
      }
    
    }

    На слова и численные значения мы реагируем очень просто - записываем их текстовое представление в рабочую переменную str типа String. При обнаружении конца строки в эту переменную записывается строка End of line.

    Если же обнаружен обычный символ, мы сравниваем его с символом кавычки. При совпадении в переменную str записывается содержимое поля sval, в котором находятся слова, обнаруженные внутри кавычек. Если же обнаруженный символ не является символом кавычки, он преобразуется в строку и записывается в переменную str.

    В заключении метод выводит строку str в стандартный поток вывода, отображая на консоли выделенный элемент потока:

    System.out.println(str);


Java | Продукты и решения | Технологии | Сервис и обучение
О компании | Партнеры | Новости | Поиск
Sun Microsystems Inc. Corporate Information Our partners News and Events Search on site Java Computing Products and Solutions Technologies and Researches Education and Service Content
Используются технологии uCoz