Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Java6

.pdf
Скачиваний:
13
Добавлен:
05.06.2015
Размер:
886.5 Кб
Скачать

public void whitespaceChars(int low, int hi)

Символы в этом диапазоне являются разделителями. При анализе они игнорируются; их единственное назначение заключается в разделении лексем — например, двух последовательных слов. Как и в случае wordChars, можно вызывать этот метод несколько раз, при этом объединение всех диапазонов определяет набор символов-разделителей.

11

public void ordinaryChar (int ch)

Символ ch является ординарным. Ординарный символ при анализе потока возвращается сам по себе, а не в виде лексемы.

public void ordinaryChars (int low, int hi)

Символы в диапазоне являются ординарными.

public void commentChar (int ch)

Символ ch начинает однострочный комментарий — символы от ch до ближайшего конца строки считаются одним длинным разделителем.

public void quoteChar (int ch)

Пары символов ch являются ограничителями для строковых констант. Когда в потоке распознается строковая константа, символ ch возвращается в качестве лексемы, а поле sval содержит тело строки (без символов-ограничителей). При чтении строковых констант обрабатываются некоторые стандартные символы Java в записи с \ (например, \t), но не все. Строки, воспринимаемые StreamTokenizer, представляют собой подмножество строк Java. Особенно жесткий запрет накладывается на использование \xxxx, \’, \" или (к сожалению) \Q, где символ Q совпадает с символом-ограничителем ch. В потоке могут присутствовать несколько разных символов-ограничителей, но строки должны начинаться и заканчиваться одним и тем же ограничителем. Другими словами, строка, которая начинается одним символом-ограничителем, продолжается до следующего вхождения того же символа; если в середине строки встречается другой символ-ограничитель, то он просто считается частью строки.

public void parseNumbers()

Указывает на необходимость выделения чисел из потока. StreamTokenizer выдает числа с плавающей точкой двойной точности и возвращает тип лексемы TT_NUMBER, а значение лексемы помещается в поле nval. Просто отказаться от поиска чисел невозможно — для этого придется либо вызвать ordinaryChars для всех символов, входящих в состав числа (не забудьте о десятичной точке и знаке “минус”), либо вызвать resetSyntax.

public void resetSyntax()

Сбрасывает синтаксическую таблицу, в результате чего все символы становятся ординарными. Если вы вызовете resetSyntax и затем начнете читать поток, то nextToken всегда будет выдавать следующий символ потока, как будто вы используете метод

InputStream.read.

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

1. wordChars(‘a’, ‘z’);

2. wordChars(‘A’, ‘Z’);

3. wordChars(128 + 32, 255);

4. whitespaceChars(0, ‘ ‘);

12

5. commentChar(‘/’);

6. quoteChar(‘"’);

7. quoteChar(‘\’’);

8. parseNumbers();

Остальные методы управляют поведением анализатора:

public void eolIsSignificant(boolean flag)

Если значение flag равно true, то конец строки является существенным, и nextToken может возвращать TT_EOL. В противном случае концы строк считаются символамиразделителями и TT_EOL никогда не возвращается. Значение по умолчанию равно false.

public void slashStarComments(boolean flag)

Если значение flag равно true, анализатор распознает комментарии вида /*...*/. Значение по умолчанию равно false.

public void slashSlashComments(boolean flag)

Если значение flag равно true, анализатор распознает комментарии от // до конца строки. Значение по умолчанию равно false.

public void lowerCaseMode(boolean flag)

Если значение flag равно true, все символы в лексемах типа TT_WORD преобразуются в нижний регистр, если имеется соответствующий эквивалент (то есть к слову применяется метод String.toLowerCase). Значение по умолчанию равно false.

Имеется также несколько методов общего назначения:

public void pushBack()

Заносит предыдущую лексему обратно в поток. Следующий вызов nextToken снова вернет ту же самую лексему. Глубина отката ограничивается одной лексемой; несколько последовательных вызовов pushBack эквивалентны одному вызову.

public int lineno()

Возвращает текущий номер строки. Обычно это бывает полезно для вывода сообщений о найденных ошибках.

public String toString()

Возвращает строковое представление последней возвращенной лексемы, включающее номер строки.

InputStreamReader и OutputStreamWriter

Пакет java.io предоставляет классы, которые позволяют выполнять конвертацию между символьными потоками Unicode и байтовыми потоками не-Unicode текста. При помощи класса InputStreamReader существует возможность преобразовывать байтовые потоки в символьные потоки. Для перевода символьных потоков в байтовые потоки используется класс

OutputStreamWriter.

При создании объектов InputStreamReader и OutputStreamWriter, задается байтовая кодировка,

13

 

вкоторую необходимо выполнить преобразование. Например, чтобы перевести текстовый файл

вкодировке UTF-8 в Unicode, необходимо сделать следующее:

FileInputStream fis = new FileInputStream("test.txt");

InputStreamReader isr = new InputStreamReader(fis, "UTF8");

Если не указать идентификатор кодировки, InputStreamReader и OutputStreamWriter будут обращаться к кодировке по умолчанию. Вы можете определить кодировку, используемую

InputStreamReader или OutputStreamWriter, вызвав метод getEncoding, таким образом:

InputStreamReader defaultReader = new InputStreamReader(fis);

String defaultEncoding = defaultReader.getEncoding();

Пример для разбора

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

1.имя файла

2.кодировка файла

3. слово для подсчета

14

 

import java.io.*;

import java.util.Scanner;

public class Reader

{

private static String _encoding; private static String _string;

public static void main(String[] args)

{

if (args.length != 3)

{

System.out.println("Wrong number of input arguments"); return;

}

 

File testFile = new File(args[0]);

 

_encoding = args[1];

 

_string1 = args[2];

 

String contents = GetContents(testFile);

 

System.out.print("File contents:\r\n" + contents);

 

System.out.println("--------------------------------------------

");

Analyze(contents);

 

}

 

static public String GetContents(File file)

{

StringBuilder contents = new StringBuilder();

try

{

if (file == null)

{

throw new IllegalArgumentException("File should not be

null.");

}

if (!file.exists())

{

throw new FileNotFoundException();

}

if (!file.canRead())

{

throw new IllegalArgumentException("File cannot be written:

" + file);

}

if (!file.isFile())

{

throw new IllegalArgumentException("Should not be a directory: " + file);

}

15

 

FileInputStream fis = new FileInputStream(file); InputStreamReader in = new InputStreamReader(fis, _encoding); BufferedReader input = new BufferedReader(in);

try

{

String line = null;

while ((line = input.readLine()) != null)

{

contents.append(line + "\r\n");

}

}

finally

{

input.close();

}

}

catch (FileNotFoundException ex)

{

System.out.println("File does not exist: " + file);

}

catch(IllegalArgumentException ex)

{

System.out.println(ex.getMessage());

}

catch (Exception ex)

{

ex.printStackTrace();

}

return contents.toString();

}

private static void Analyze(String contents)

{

Scanner scanner = new Scanner(contents);

int stringCount = 0;

while (scanner.hasNextLine())

{

Scanner s = new Scanner(scanner.nextLine());

while (s.hasNext())

{

String word = s.next();

if (word.contentEquals(_string)) stringCount++;

}

s.close();

}

scanner.close();

16

 

System.out.println(_string + " — " + stringCount);

 

}

}

Варианты заданий

1. Есть файл в определенной кодировке. Содержимое файла: n-строк. Необходимо упорядочить строки по алфавиту (упорядочить порядок строк в файле, а не символов в этих строках) и записать их в новый файл.

2. Есть файл в определенной кодировке. Содержимое файла: n-строк. Необходимо заме-

нить все символы табуляции в файле на пробел; удалить множественные пробелы, оста-

17

вив лишь один. Записать всё в новый файл.

3.Создать список всех файлов и папок, находящихся внутри какой-то директории (в том числе и вложенных файлов\папок вложенных в эту директорию), путь к которой указывается как параметр программе. Список записать в файл.

4.Создать программу шифратор, которая записывает каждый новый символ в файл в разных кодировках (последовательность которых, к примеру, повторяются каждые 10 символов). Аналогично сделать возможность дешифровки созданного файла с записью расшифрованного содержимого в новый файл.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]