МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра САПР
ЗВІТ
До виконання лабораторної роботи №7
На тему: “ Програмування введення-виводу в Java”
З курсу “ Об’єктно-орієнтоване програмування”
Львів – 2009
МЕТА РОБОТИ
Метою роботи є придбання навиків використання потоків введення-висновку в програмах на мові Java.
КОРОТКІ ТЕОРЕТИЧНІ ВІДОМОСТІ
3.1. Робота з файлами в Java
Інформація на пристроях зовнішньої пам'яті зберігається у файлах - іменованих областях на диску, дискеті або іншому машинному носії. Структура (як правило, ієрархічна) розміщення файлів на носіях інформації, а також види і правила завдання атрибутів файлу (імені, типу, дати створення і/або модифікації і т.п.) називається файловою системою. Файлові системи в різних операційних системах, як правило, відрізняються один від одного.
3.1.1. Клас File
Клас File дозволяє одержати від системи всі дані, починаючи з імені файлу і закінчуючи часом останньої його модифікації. Клас File можна використовувати для створення нових каталогів, а також для видалення і перейменування файлів. Для створення об'єкту File потрібно викликати один з трьох конструкторів класу:
File(String path)
File(String path, String name)
File(File dir, String name)
Перший конструктор створює об'єкт File з вказаним повним ім'ям файлу. Другий конструктор створює цей об'єкт, використовуючи окремо шлях і ім'я файлу, а третій створює об'єкт, використовуючи шлях і ім'я файлу, при цьому шлях визначається іншим об'єктом File.
Методи для роботи з файлами і каталогами класу File приведені в таблиці.
Метод
Опис
public String getName()
Визначає ім'я файлу.
public String getPath()
Визначає відносний шлях до файлу (наприклад з даного каталога).
public String getAbsolutePath()
Визначає повне ім'я файлу (шлях до каталога з кореневого каталога). Цей шлях називається також абсолютним шляхом до файлу.
public String getParent()
Визначає батьківський каталог файлу.
public boolean exists()
Повертає значення true, якщо файл існує.
public boolean canWrite()
Повертає значення true, якщо у файл можна записувати.
public boolean canRead()
Повертає значення true, якщо файл можна читати.
public boolean isFile()
Повертає значення true, якщо файл.
public boolean isDirectory()
Повертає значення true, якщо каталог.
public boolean isAbsolute()
Повертає значення true, якщо ім'я файлу повне.
public long lastModified()
Повертає час останньої модифікації файлу.
public long length()
Повертає довжину файлу.
public boolean mkdir()
Створює каталог.
public boolean renameTo(File newName)
Перейменовує файл.
public boolean delete()
Видаляє файл.
public boolean mkdirs()
Створює дерево каталогів..
public String[] list()
Створює рядковий масив імен файлів і підкаталогів в каталозі.
public String[] list(FilenameFilter filter)
Створює рядковий масив імен всіх файлів, задовольняючих фільтру імен по інтерфейсу FilenameFilter.
public File[] listFiles()
Створює масив об'єктів класу File в каталозі.
public File[] listFiles(FilenameFilter filter)
Створює масив об'єктів класу File, задовольняючих фільтру імен по інтерфейсу FilenameFilter.
public File[] listFiles(FileFilter filter)
Створює рядковий масив об'єктів класу File, задовольняючих фільтру імен по інтерфейсу FileFilter.
Часто потрібно обмежити кількість файлів, що повертаються методами list() або listFiles(), щоб включати в список тільки ті з них, імена яких відповідають деякому зразку або фільтру. Для цього цій меті можна використовувати переобтяжену форму методів list() і listFiles():
public String[] list(FilenameFilter filter)
public File[] listFiles(FilenameFilter filter)
У цих формах як параметр задається об'єкт класу, який реалізує інтерфейс типу FilenameFilter.
Інтерфейс FilenameFilter визначає єдиний метод accept(), який має наступний вигляд:
public abstract boolean accept(File dir, String name)
Цей метод повертає true для файлів каталога dir, які повинні бути включені у відфільтрований список (з іменами name), і повертає false для тих файлів, які повинні бути виключені із списку (імена яких не співпадають з name).
При використанні методу
public File[] listFiles(FileFilter filter)
файли фільтрується не просто по іменах, а по їх повних іменах (з шляхами в ієрархії каталогів).
При цьому повертаються файли з тими іменами шляху, які задовольняють файловому фільтру filter. Інтерфейс FileFilter визначає тільки один метод, accept(), який викликається одного разу для кожного файлу в списку. Його загальна форма:
boolean accept(File path)
Метод повертає true для файлів, які повинні бути включені в список (тобто тих файлів, які вказані в path), і false - для тих файлів, які повинні бути виключені (не вказані в path).
Змінна
public final static char separatorChar
класу File повертає символ розділення імен каталогів і файлів ("\" в Windows і "/" - в Unix), а змінна
public final static char pathSeparatorChar
містить символ-роздільник шляхів в списку (";" у Windows і ":" - в Unix).
3.1.2. Вибір файлів в Swing
Клас JFileChooser в Swing забезпечує діалогове вікно для вибору каталогів і файлів. Основні конструктори цього класу:
JFileChooser()
JFileChooser(File currentDirectory)
JFileChooser(String currentDirectoryPath)
дозволяють відкрити вікно вибору файлів як для всіх файлів, так і для конкретного каталога.
Методи класу JFileChooser приведені в таблиці:
Метод
Опис
public File getSelectedFile()
Отримання вибраного файлу.
public File[] getSelectedFiles()
Отримання вибраних файлів.
public void setSelectedFile(File file)
Установка вибраного файлу.
public void setSelectedFiles(File[] selectedFiles))
Установка вибраних файлів.
public File getCurrentDirectory()
Одержати вибраний каталог.
public void setCurrentDirectory(File dir)
Встановити вибраний каталог.
public String getDescription(File f)
Отримання характеристик файлу.
public void setFileFilter(FileFilter filter)
Установка фільтру для імен файлів, що виводяться.
public FileFilter getFileFilter()
Отримання фільтру для імен файлів, що виводяться.
Для відстежування подій, пов'язаних з кнопками в діалоговому вікні вибору файлів, необхідно реалізувати інтерфейс і додати або видалити блок прослуховування для кнопок діалогового вікна вибору файлів за допомогою методів
public void addActionListener(ActionListener l)
і
public void removeActionListener(ActionListener l)
класу JFileChooser.
3.2. Організація введення-висновку в Java
Всі дані в комп'ютерній системі проходять від пристроїв введення через комп'ютер до пристроїв висновку. Аналогія з перетікаючими даними викликала до життя термін ЀпотокиЀ (streams). Два терміни в Java, що означають різні поняття: thread і stream, перекладаються російською мовою одним і тим же словом - потік. Щоб уникнути плутанини, в цьому занятті ми використовуватимемо для першого терміну слова Ѐпотік обчисленьЀ, а для другого - просто ЀпотікЀ.
Потоком називається канал обміну інформацією між її джерелом і одержувачем. На одному кінці потоку завжди знаходиться програма на Java. Якщо вона служитиме джерелом даних, то даний потік буде вихідним, якщо програма знаходитиметься на приймаючій стороні - то вхідним.
Починаючи з версії JDK 1.1, в Java визначені два типу потоку: байтовий і символьний потоки.
Байтовий потік або оперує з байтами і використовується при читанні (input stream) або записі (output stream) даних в двійковому коді.
Символьний потік (reader або writer) використовується для введення і виведення символів. У старіших мовах, наприклад C або C++, поняття символ і байт є еквівалентними, оскільки символи мали однобайтове кодування. Проте в Java символ не є еквівалентом байта, оскільки є 16-бітовим елементом, призначеним для розміщення кодів Unicode.
У мові Java потоки представляються класами. Прості з цих класів працюють з базовими потоками введення і висновку, що мають основні засоби роботи з потоками. Від базових класів породжуються інші класи, більшою мірою орієнтовані на конкретний тип введення або висновку.
Всі класи введення-висновку Java описані в пакеті java.io.
Слід помітити, що практично кожен метод будь-якого класу в пакеті java.io здатний генерувати ту або іншу форму виняткової ситуації IOException. Тому для поліпшення стилю програмування слід завжди поміщати виклики операцій введення-висновку в блоки try і catch.
3.3. Байтові потоки введення-висновку
3.3.1. Класи InputStream і OutputStream
Абстрактний клас InputStream є базовим потоком введення. Клас містить єдиний конструктор
InputStream().
Методи класу InputStream приведені в таблиці:
Метод
Опис
public int read()
throws IOException
Прочитує з вхідного потоку окремі байти як цілі числа, повертаючи значення -1, коли більше нічого читати.
public int read(byte b[]) throws IOException
Прочитує безліч байтів в байтовий масив, повертаючи кількість реально введених байтів.
public int read(byte b[], int off, int len) throws IOException
Також читає дані в байтовий масив, проте дозволяє вказати зсув (off) в масиві, з якого почнеться запис символів, а також задати максимальне число прочитуваних байтів (len).
public long skip(long n) throws IOException
Пропускає байти в потоці.
public int available() throws IOException
Повертає кількість байтів, наявних в даний момент в потоці.
public void mark(int readlimit)
Позначає позицію readlimit в потоці.
void reset() throws IOException
Повертається до відміченої позиції потоку.
public boolean markSupported()
Повертає булеве значення, вказуюче на те, чи можна в даному потоці відзначати позиції і повертатися до ним.
public void close() throws IOException
Закриває потік.
Абстрактний клас OutputStream, забезпечує базові функції для всіх вихідних потоків і має єдиний конструктор
OutputStream().
Методи класу OutputStream приведені в таблиці.
Метод
Опис
public void write(int b) throws IOException
Записує байт в потік.
public void write(byte b[]) throws IOException
Записує в потік всі байти, що містяться в заданому байтовому масиві.
public void write(byte b[], int off, int len) throws IOException
Записує дані з байтового масиву, указуючи початковий зсув (off) і кількість байтів, що виводяться (len).
public void flush() throws IOException
Виконує примусовий запис всіх буферізірованних вихідних даних.
public void close() throws IOException
Закриває потік.
3.3.2. Класи FileInputStream і FileOutputStream
Клас FileInputStream створює (відкриває) об'єкт, який можна використовувати для читання байтів з файлу за допомогою одного з наступних конструкторів:
FileInputStream (String filepath)
throws FileNotFoundException
FileInputSream(File file) throws FileNotFoundException
Клас FileInputStream реалізує методи available(), close(), skip() і всі форми методу read(). Крім того, в цьому класі доданий метод
public final FileDescriptor getFD() throws IOException
що повертає об'єкт FileDescriptor для відкритого файлу і метод
protected void finalize() throws IOException
для очищення зв'язку з файлом і виклику методу close().
Клас FileOutputStream створює об'єкт OutputStream, який можна застосовувати для запису байтів у файл. Звичайно використовуються наступні конструктори цього класу:
FileOutputStream(String filePath)
FileOutputStream(File fileObj)
FileOutputStream(String filePath, boolean append)
Параметри в цих конструкторах мають той же сенс, що і в конструкторах класу FileInputStream. Якщо параметр append в останньому конструкторі рівний true, файл (якщо він вже існує) відкривається в режимі додавання, інакше файл записується наново.
Клас FileOutputStream реалізує метод close() і всі форми методу write() класу OutputStream, а також використовує свої власні методи getFD() і finalize(), аналогічні однойменним методам класу FileInputStream.
3.3.3. Класи ByteArrayInputStream і ByteArrayOutputStream
Клас ByteArrayInputStream є реалізацією вхідного потоку, яка використовує байтовий масив як джерело. Цей клас має два конструктори, кожний з яких використовує байтовий масив як джерело даних:
ByteArrayInputStream(byte array[])
ByteArrayInputStream (byte array [], int off, int len)
Тут байтовий масив array - це джерело введення. Другий конструктор створює об'єкт, що складається з байтового масиву, який починається з позиції off і має довжину len байтів.
Клас ByteArrayInputStream реалізує методи read() класу InputStream для читання оного байта і частини масиву. Реалізація методу reset() у цьому класі має наступну особливість: якщо метод mark() не викликався, то reset() встановлює потоковий покажчик на початок потоку, який в цьому випадку є початком масиву байт, передаваного конструктору. Цю особливість можна використовувати, наприклад, для читання одного і того ж потоку введення двічі.
При виконанні операції висновку масив байтів можна переслати в локальну пам'ять комп'ютера. Конкретним класом вивідного потоку OutputStream, здатним вирішити це завдання, є ByteArrayOutputStream.
Клас ByteArrayOutputStream має наступні два конструктори:
ByteArrayOutputStream()
ByteArrayOutputStream(int len)
Першому з них не передається ніяких параметрів, тому він створює буфер розміром 32 байт. При необхідності розмір буфера може бути збільшений. Проте якщо збільшення виконуватиметься на декілька байтів за кожне звернення, то в деяких системах це може викликати сильну фрагментацію пам'яті. Якщо наперед відомо, що буде потрібно буфер розміром, наприклад, в 1024 байти, слід використовувати другу версію конструктора, якому передається один параметр.
На додаток до методів, успадкованих від базового класу OutputStream, клас ByteArrayOutputStream підтримує наступні методи:
Метод
Описание
public int size()
Повертає поточний розмір буфера.
public void reset()
Скидає значення лічильника вивідного потоку в 0, так, що вже накопичений вміст буфера вивідного потоку втрачається.
public byte[] toByteArray()
Перетворить дані вивідного потоку в новий масив байтів.
public String toString()
Перетворить вміст буфера в рядок відповідно до правил кодування символів за умовчанням.
public void writeTo(OutputStream out) throws IOException
Записує весь вміст потоку в інший потік.
Клас ByteArrayOutputStream можна використовувати як один з елементів для побудови складніших об'єктів, включаючи процедури взаємодії між процесами, або для заміни інших потоків (наприклад, потоку мережевих даних) в процесі тестування.
3.3.4. Клас SequenceInputStream
Клас SequenceInputStream дозволяє зчіплювати безліч об'єктів вхідного потоку. Основна форма конструктора цього класу використовує як параметри два об'єкти класу InputStream або його підкласів:
SequenceInputStream(InputStream firstStream
InputStream secondStream)
Клас виконує запити читання першого об'єкту типу InputStream (параметр firstStream), поки він не закінчиться, і потім перемикається на другій (параметр secondStream). У свою чергу, використовуючи як одного з об'єктів об'єкт класу SequenceInputStream, можна організувати введення більш ніж двох об'єктів вхідного потоку.
Клас SequenceInputStream реалізує методи available() і close(), а також методи read() для читання байта і частини масиву класу InputStream.
3.3.5. Класи BufferedInputStream і BufferedOutputStream
Байтовий буферізірованний потік розширює класи фільтрованого потоку, приєднуючи буфер пам'яті до потоків введення/висновку. Такий буфер дозволяє виконувати операції введення-висновку (використовуючи внутрішній буфер) не з одним, а з декількома байтами одночасно, і, отже, збільшує ефективність роботи програми. За наявності буфера стає можливим такі операції, як пропуск байтів, маркіровка і встановлення заново потоку. Буферізірованниє потокові класи - це класи BufferedInputStream і BufferedOutputStream.
Клас BufferedInputStream містить два конструктори:
BufferedInputStream (InputStream in)
BufferedInputStream(InputStream in, int size)
Перша форма створює буферізірованний потік, використовуючи розмір буфера, заданий за умовчанням. У другій формі розмір буфера передається в параметрі size. Змінна
protected byte[] buf
класу BufferedInputStream містить внутрішній буфер вхідного потоку, а змінна
protected int count
містить лічильник кількості введених байт (ця величина міняється від нуля до величини масиву size).
Клас BufferedInputStream підтримує всі методи класу InputStream, за винятком методу read() для читання масиву байт.
Клас BufferedOutputStream є ефективним варіантом класу OutputStream, що виконує запис байтів у внутрішній буфер, який потім може бути виведений в потік нижнього рівня. Конструктори цього класу
BufferedOutputStream(OutputStream out)
BufferedOutputStream(OutputStream out, int size)
створюють об'єкт BufferedOutputStream з буфером за умовчанням (512 байт) або з буфером заданого розміру.
Властивість цього класу
protected byte[] buf
повертає вміст внутрішнього буфера, а властивість
protected int count
- кількість виведених в буфер байт. Клас BufferedOutputStream реалізує методи write()записи одного байта і частини масиву байт, а також методи close() і flush() класу OutputStream.
3.3.6. Клас PushbackInputStream
Одне із застосувань буферизації - виконання повернення ліченого байта назад у вхідний потік (операція pushback). Цю можливість в Java здійснює клас PushbackInputStream. Цей клас має наступні конструктори:
PushbackInputStream (InputStream inputStream)
PushbackInputStream( InputStream inputStream, int size)
Перша форма створює потоковий об'єкт, який дозволяє повернути один байт у вхідний потік. Друга форма створює потік, який має спеціальний pushback-буфер завдовжки size байт. Він дає можливість виконувати повернення декількох байтів у вхідний потік.
Окрім методів available(), close(), markSupported(), read() і read() для читання частини масиву байт класу InputStream, в PushbackInputStream визначений метод unread() у наступних формах:
void unread(int b)
void unread(byte b[])
void unread(byte b [], int off, int len)
Перша форма повертає молодший байт параметра b. Повернений байт буде прочитаний наступним за unread() викликом read(). Друга форма повертає групу байтів - весь буферний масив b[]. Третя форма забезпечує отримання частини масиву b[] (len байт, починаючи з індексу off). Якщо здійснюється спроба повернути байт при заповненому буфері повернення, буде кинуте виключення класу IOException.
3.3.7. Клас PrintStream
Клас PrintStream дозволяє вивести в потік нижнього рівня представлення даних примітивного, рядкового або об'єктного типа, яке вони матимуть при друці.
Два конструктори класу PrintStream:
PrintStream(OutputStream out)
PrintStream(OutputStream out, boolean autoFlush)
створюють новий потік для друку. Якщо другий параметр в другому конструкторі рівний true, то вивідний буфер очищатиметься в одній з наступних ситуацій: записаний масив байт, викликаний один з методів println() або у вивідний потік записується символ "\n".
Крім реалізації методів write() записи масиву байт і частини масиву байт, а також методів flush() і close() класу OutputStream, в класі PrintStream визначені також наступні методи:
protected void setError() - установка стан помилки для потоку в true;
· public boolean checkError() - очищення буфера потоку з перевіркою його стану помилки.
Окрім цього, в класі визначені два вже відомих методу:
public void print(аргумент)
і
public void println(аргумент).
Як аргументи при виклику цих методів можуть бути задані: boolean b, char з char[] s, float f, double d, int i, long l, String s і Object obj.
3.4. Символьні потоки введення-висновку
3.4.1. Класи Reader і Writer
Функції класів InputStream і OutputStream для символьних потоків виконують абстрактні класи Reader і Writer.
Клас Reader визначає модель символьного вхідного потоку. Конструктори класу
protected Reader()
protected Reader(Object lock)
визначають новий ввідний символьний потік. Критичні секції потоку в першому конструкторі синхронізуються з самим ввідному потоці, а в другому - з вказаним об'єктом lock.
Короткий опис методів класу Reader приведений в таблиці
Метод
Опис
public int read()
throws IOException
Прочитує з вхідного потоку окремі символи як цілі числа, повертаючи значення -1, коли більше нічого читати.
public int read(char с[]) throws IOException
Прочитує безліч символів в символьний масив, повертаючи кількість реально введених символів.
public int read(char с[], int off, int len) throws IOException
Також читає дані в символьний масив, проте дозволяє вказати зсув (off) в масиві, з якого почнеться запис символів, а також задати максимальне число прочитуваних символів (len).
public long skip(long n) throws IOException
Пропускає символи в потоці.
public boolean ready() throws IOException
Повертає true, якщо потік готовий до читання, і false - інакше.
public void mark(int readlimit)
Позначає позицію readlimit в потоці.
public boolean markSupported()
Повертає булеве значення, вказуюче на те, чи можна в даному потоці відзначати позиції і повертатися до ним.
void reset() throws IOException
Повертається до відміченої позиції потоку.
public void close() throws IOException
Закриває потік
Клас Writer визначає модель потокового символьного висновку. Конструктори класу
protected Writer()
protected Writer (Object lock)
визначають новий вивідний символьний потік аналогічно конструкторам класу Reader.
Методи класу Writer представлені в наступній таблиці
Метод
Опис
public void write(int с) throws IOException
Записує символ у вихідний потік.
public void write(char с[]) throws IOException
Записує у вихідний потік всі символи, що містяться в заданому символьному масиві.
public void write(char с[], int off, int len) throws IOException
Записує дані з символьного масиву, указуючи початковий зсув (off) і кількість символів, що виводяться (len).
public void write(String str) throws IOException
Записує рядок у вихідний потік.
public void write(String str, int off, int len) throws IOException
Записує дані з рядка, указуючи початковий зсув (off) і кількість символів (len) рядка, що виводяться.
public void flush() throws IOException
Виконує примусовий запис всіх буферізірованних вихідних даних.
public void close() throws IOException
Закриває вихідний потік.
3.4.2. Класи InputStreamReader і OutputStreamWriter
Класи InputStreamReader і OutputStreamWriter є переходникамі між байтовими і символьними потоками.
Клас InputStreamReader перетворить байтовий потік в символьний потік. Основний конструктор цього класу:
InputStreamReader(InputStream in)
Цей конструктор створює з байтового потоку in символьний потік відповідно до кодування за умовчанням (кодування за умовчанням залежить від реалізації віртуальної машини Java і встановлених для неї локальних значень).
Для класу InputStreamReader визначені наступні методи read() для читання одного символу або частини масиву символів, методи ready() і close() класу Reader.
Клас OutputStreamWriter перетворить символьний потік в байтовий потік. Основний конструктор цього класу:
OutputStreamWriter(OutputStream out)
Цей конструктор створює з символьного потоку out байтовий потік відповідно до кодування за умовчанням.
Для виведення символів в класі OutputStreamWriter використовуються перші три форми методу write(), метод flush() і метод close() класу Writer.
3.4.3. Класи FileReader і FileWriter
Клас FileReader створює об'єкт, який можна використовувати для читання вмісту файлу. Для створення об'єкту класу FileReader можна використовувати один з наступних конструкторів:
FileReader(String fileName) throws FileNotFoundException
FileReader(File file) throws FileNotFoundException
У першому конструкторі як параметр задається повне ім'я файлу, а в другому - об'єкт класу File .
Клас FileReader успадковує методи read() для читання символу і частини масиву символів, close() і ready() класу InputStreamReader, а також метод read() для читання масиву символів, mark(), markSupported(), reset() і skip() класу Reader.
Клас FileWriter створює об'єкт, який можна використовувати для запису у файл. Конструктори цього класу:
FileWriter(String fileName) throws IOException
FileWriter(File file) throws IOException
FileWriter(String fileName, boolean append)
throws IOException
задають в параметрах або повне ім'я файлу (параметр fileName), або об'єкт класу File (параметр file). Другий параметр append останнього конструктора задає режим запису у файл: якщо true, то висновок додається в кінець файлу, якщо false - файл перезаписується. При створенні об'єкту класу FileWriter, якщо файл існує, він відкривається, якщо файл не існує, він буде створений і відкритий. Клас FileWriter успадковує перші три форми методу write(), метод flush() і метод close() класу OutputStreamWriter.
3.4.4. Класи CharArrayReader і CharArrayWriter
Клас CharArrayReader є реалізацією вхідного потоку, яка використовує символьний масив як джерело. Для цього класу визначені наступні конструктори:
CharArrayReader(char з[ ])
CharArrayReader(char з[ ], int off, int len)
Перший конструктор створює з масиву символів з вхідний потік, а другий конструктор читає len символів масиву з, починаючи із зсуву off.
Клас реалізує наступні методи класу Reader: skip(), ready(), reset(), mark(), markSupported(), close(), а також методи read() для читання одного символу і частини масиву символів.
Клас CharArrayWriter реалізує вихідний потік, що записує дані в символьний масив. Цей клас має два конструктори:
CharArrayWriter()
CharArrayWriter (int initialSize)
У першій формі створюється буфер з розміром, заданим за умовчанням. У другій формі - буфер з розміром, вказаним в параметрі initialSize. Буфер міститься в полі buf класу CharArrayWriter. Якщо необхідно, розмір буфера буде збільшений автоматично. Число символів, що зберігаються в буфері, міститься в полі count класу CharArrayWriter. І buf і count оголошені з модифікатором protected, тобто є захищеними полями.
Разом з реалізацією методів write() для запису одного символу, частини масиву символів і частини рядка, flush() і close() класу Writer, в класі CharArrayWriter реалізовані наступні власні методи
Метод
Опис
public char[] toCharArray()
Повертає копію даних, що вводяться.
public String toString()
Перетворить дані, що вводяться, в рядок.
public int size()
Повертає поточний розмір буфера.
public void writeTo(Writer out) throws IOException
Записує вміст буфера в інший символьний потік.
4.5. Клас PrintWriter
Клас PrintWriter виводить форматоване представлення об'єктів в текстовий вивідний потік.
Для класу PrintWriter визначені наступні конструктори:
PrintWriter(OutputStream out)
PrintWriter(OutputStream out, boolean autoFlush)
PrintWriter(Writer out)
PrintWriter(Writer out, boolean autoFlush)
Перший і другий конструктори створюють новий об'єкт PrintWriter з існуючого вивідного байтового потоку out, третій і четвертий конструктори створюють новий об'єкт PrintWriter з існуючого вивідного символьного потоку out (при цьому створюється проміжний об'єкт OutputStreamWriter, що перетворює символи в байти з використанням кодування символів за умовчанням). Перший і третій конструктори виводять символи у вихідний потік без автоматичного звільнення буфера при переході на новий рядок. Завдання для autoFlush значення true в другому і четвертому конструкторах викликає очищення буферів при використанні методів println().
Методи цього класу не кидають виключення введення-висновку. Замість них використовуються методи даного класу
protected void setError()
і
public boolean checkError()
що відповідно встановлює стан помилки в true і перевіряючий стан помилки.
Методи print() і println() класу PrintWriter мають ті ж аргументи, що і відповідні методи класу PrintStream, і діють аналогічно.
Крім того, для класу PrintWriter визначені всі методи класу Writer.
3.5. Консольне введення
Вводити дані з клавіатури, не створюючи власних потоків можна за допомогою об'єкту System.in, класу InputStream, що є екземпляром. Оскільки об'єкт є екземпляром класу, йому доступні всі методи цього класу.
Ознакою закінчення введення з клавіатури може служити введення заданого символу або послідовності символів, а також натиснення клавіш Ctrl+Z.
Хоча можна обробляти вхідний потік з клавіатури як байтовий, в Java 2 рекомендується перетворити байтовий потік, що вводиться, в символьний, використовуючи об'єкт класу InputStreamReader, а потім перетворити його в буферне введення з використанням класу BufferedReader.
3.6. Клас StreamTokenizer
При читанні символьних потоків дуже часто потрібно розбивати дані на окремі слова. Слово - це послідовність символів, відокремлена від інших слів пропуском або деяким символом-роздільником. Для вирішення подібного завдання в Java існує спеціальний клас StreamTokenizer, конструктору якого як параметр передається посилання на вхідний символьний потік.
Властивості цього класу визначають наступні типи слів:
TT_EOF - кінець файлу;
· TT_EOL - кінець рядка;
· TT_NUMBER - число;
· TT_WORD - текстове поле.
Окрім, того, властивість
int nval
містить значення поточного слова, якщо воно число, а властивість
String sval
містить значення поточного слова, якщо воно - рядок. Властивість
int ttype
містить тип тільки що прочитаного слова.
Клас StreamTokenizer включає безліч різних методів, основні з яких приведені в таблиці:
Метод
Опис
void commentChar (int char)
Визначає символ однорядкового коментаря.
void eolIsSignificant(boolean flag)
Дозволяє вказати, чи слід рахувати ознаку кінця рядка роздільником слів (якщо так, то flag - true, інакше - false).
int lineno()
Повертає номер поточного рядка.
void lowerCaseMode(boolean flag)
Дозволяє перевести екземпляр об'єкту в режим примусового перекладу всіх виділених слів в нижній регістр.
int nextToken()
Читає наступне слово і повертає його тип. Крім того, тип слова встановлюється в ttype.
void ordinaryChar()
Дозволяє встановити, які символи слід вважати простими. Прості символи обробляються як односимвольна лексема незалежно від того, чи є вона частиною роздільника рядків, використовується в коментарі або входить до складу звичайного слова.
void ordinaryChars(int low, int high)
Встановлює, що символи з кодами в діапазоні від low до high є простими.
void parseNumbers()
Дозволяє визначити, чи слід робити спроби розпізнавання чисел і перетворення їх у відповідну числову форму.
void pushBack()
Вимушує клас при наступному виклику методу nextToken() здійснити повернення останнього виділеного слова назад у вхідний потік.
void quoteChar(int char)
Визначає символ, використовуваний для виділення текстових рядків.
void resetSyntax()
Після виклику цього методу даний екземпляр об'єкту використовуватиме синтаксичну таблицю, що приймається за умовчанням, в якій всі символи є "простими".
void slashSlashComments(boolean flag)
Задає режим обробки однорядкових коментарів, виконаних в стилі C++.
void slashStarComments(boolean flag)
Задає режим обробки багаторядкових коментарів, виконаних в стилі C.
String toString()
Повертає представлення поточної лексеми у вигляді об'єкту класу String.
void whitespaceChars (int low, int high)
Задає символи, що сприймаються як пропуски.
void wordChars (int low, int high)
Встановлює, які символи можуть входити до складу слів.
Клас StreamTokenizer можна використовувати як основу для створення підпрограм обробки текстів, що вводяться з вхідного потоку.
Індивідуальне завдання
Варіант 15
Створіть програму для підрахунку частоти повторення заданого слова в текстовому файлі з використанням класу StreamTokenizer. Компоненти графічного вікна: напис "Пошук кількості повторень слова в текстовому файлі" у області North, у області Center розміщений об'єкт класу JFileChooser, у області South розміщені напис "Слово пошуку:", текстове поле для введення слова пошуку, прапорець з написом "Облік регістра", кнопка "Пошук", напис "Частота повторення:" і текстове поле для виведення частоти повторення слова. рядків. Виведення частоти повторення слова виконується при натисненні кнопки.
Код програми
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class lab7 extends JFrame
{
JLabel MainJLabel = new JLabel("Пошук кількості повторень слова в текстовому файлі");
JLabel SearchJLabel = new JLabel("Слово пошуку:");
JFileChooser MainFileChooser = new JFileChooser();
JTextField SearchJTextField = new JTextField();
JCheckBox RegisterCheckJCheckBox = new JCheckBox("Облік регістра");
boolean flagCheckBox;
JButton SearchJButton = new JButton("Пошук");
JLabel FreqOfRepeatingJLabel = new JLabel("Частота повторення:");
JTextField FreqOfRepeatingJTextField = new JTextField();
JLabel tmpJLabel = new JLabel();
StreamTokenizer WorkFileStreamTokenizer;
public lab7(String name)
{
setTitle(name);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLayout(new BorderLayout());
setSize(500,450);
setLocation(0,0);
MainJLabel.setSize(400,20);
MainJLabel.setLocation(0,0);
MainFileChooser.setSize(490,300);
MainFileChooser.setLocation(0,20);
MainFileChooser.addActionListener
(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand()==MainFileChooser.APPROVE_SELECTION)
{
try{WorkFileStreamTokenizer = new StreamTokenizer(new FileReader(MainFileChooser.getSelectedFile()));}
catch(FileNotFoundException fnfe){};
}
else if(e.getActionCommand()==MainFileChooser.CANCEL_SELECTION)WorkFileStreamTokenizer=null;
}
}
);
SearchJLabel.setSize(200,20);
SearchJLabel.setLocation(0,320);
SearchJTextField.setSize(290,20);
SearchJTextField.setLocation(200,320);
RegisterCheckJCheckBox.setSize(200,20);
RegisterCheckJCheckBox.setLocation(300,340);
RegisterCheckJCheckBox.addActionListener
(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
flagCheckBox = RegisterCheckJCheckBox.isSelected();
}
}
);
SearchJButton.setSize(100,20);
SearchJButton.setLocation(0,360);
SearchJButton.addActionListener
(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(WorkFileStreamTokenizer==null)FreqOfRepeatingJTextField.setText("Спочатку виберіть файл!");