План
Актуальность ввода и вывода информации
при создании программ
Концепция потоков ввода/вывода
Пакет java.io. Классы потоков ввода/вывода
в Java. Их иерархия.
Базовые классы InputStream и
OutputStream.
Работа с символьными данными с
помощью иерархий Reader и Writer
Реализация потоков. Ввод и вывод из
файлов.
Сериализация, чтение и запись объектов.
Описание задачи
Подавляющее большинство программ
обменивается данными с внешним миром.
Это делают любые сетевые приложения - они
передают и получают информацию от других
компьютеров и специальных
устройств, подключенных к сети.
Оказывается удобным точно таким же
образом представлять обмен данными
между устройствами внутри одной машины.
Так, например, программа может считывать
данные с клавиатуры и записывать их в
файл, или же наоборот - считывать данные из
файла и выводить их на экран
Описание задачи
Т.о., устройства, откуда может
производиться считывание информации,
могут быть самыми разнообразными -
файл, клавиатура, (входящее) сетевое
соединение и т.д.
То же самое касается и устройств вывода -
это может быть файл, экран монитора,
принтер, (исходящее) сетевое
соединение и т.п.
В конечном счете, все данные в
компьютерной системе в процессе
обработки передаются от устройств
ввода к устройствам вывода
Система ввода/вывода
Обычно часть вычислительной
платформы, которая отвечает за обмен
данным, так и называется - система
ввода/вывода. В Java она представлена
пакетом java.io (input/output).
Реализация системы ввода/вывода
осложняется не только широким спектром
источников и получателей данных, но
еще и различными форматами
передачи информации.
Ею можно обмениваться в двоичном
представлении, символьном или
текстовом с применением некоторой
кодировки (только для русского языка их
насчитывается от 4 штук) или передавать
числа в различных представлениях.
Виды доступа
Доступ к данным может
потребоваться как последовательный
(например, считывание HTML
страницы), так и произвольный
(сложная работа с несколькими
частями одного файла).
Зачастую для повышения
производительности применяется
буферизация
Потоки данных
В Java для описания работы по
вводу/выводу используется
специальное понятие поток данных
(stream).
Поток данных связан с некоторым
источником или приемником
данных, способных получать или
предоставлять информацию
Потоки ввода и вывода
потоки делятся на входные - читающие
данные, и на выходные -
передающие (записывающие)
данные.
Введение концепции stream позволяет
отделить
программу, обменивающуюся
информацией одинаковым образом
с любыми устройствами, от
низкоуровневых операций с такими
устройствами ввода/вывода
Объекты потоков
В Java потоки представляются объектами.
Входят в пакет java.io.
Разнообразны и отвечают за различную
функциональность.
Разделены на две части - входные и
выходные (для ввода и вывода данных)
Базовые универсальные классы позволяют
считывать и записывать информацию
именно в виде набора байт
Если требуется записать в поток данные
других типов или целый объект, он сначала
преобразуется в набор байт
(сериализуется)
При считывании происходит обратное
преобразование
Класс InputStream
Абстрактный базовый класс для потоков ввода
(чтения) двоичных данных
Основные методы:
int read() - читает 1 байт из потока и возвращает
его значение. Если достигнут конец потока (нет
больше информации для чтения), возвращает
значение -1.
int read(byte[] arr) - считывает данные в массив.
Пытается считать arr.length байт. Возвращает
число реально считанный байт.
int read(byte[] arr, int offset, int count) - позволяет
считать count байт в массив, начиная с позиции
offset (если мы хотим заполнить не весь
массив).
int available() - возвращает кол-во доступных для
чтения байт
void close() - закрывает поток
Если чтение невозможно, выбрасывается
исключение java.io.IOException
Класс OutputStream
Абстрактный базовый класс для потоков
вывода (записи) двоичных данных
Основные методы:
void write(int char) - запись в поток 1 байта.
void write(byte[] arr) - запись всех байтов из
массива
void write(byte[] arr, int offset, int count) -
запись count байтов из массива, начиная с
позиции offset.
void flush() - принудительная запись данных из
буфера в поток.
void close() - закрывает поток
Если чтение невозможно, выбрасывается
исключение java.io.IOException
Реализации потоков
ByteArrayInputStream и ByteArrayOutputStream
FileInputStream и FileOutputStream
PipedInputStream и PipedOutputStream
StringBufferInputStream
SequenceInputStream
FilterInputStreeam и FilterOutputStream
BufferedInputStream и BufferedOutputStream
LineNumberInputStream
PushBackInputStream
PrintStream
DataInputStream и DataOutputStream
ObjectOutputStream
Пример – работа с файлами
String inputFileName = "d:input.txt";
String outputFileName = "d:output.txt";
try {
FileInputStream fis = new FileInputStream(inputFileName);
System.out.println("Файл " + inputFileName + " открыт для чтения");
System.out.println("Содержимое файла:");
int size = fis.available();
byte mas[] = new byte [size];
int count = fis.read(mas);
for (byte b : mas) {
System.out.print((char)b);
}
System.out.println("Считано байт: " + count);
fis.close();
// запись в файл
DataOutputStream dos = new DataOutputStream(new
FileOutputStream(outputFileName));
dos.writeDouble(3.14);
dos.writeInt(55);
dos.writeUTF("Тестовая строка 1n");
dos.writeUTF("Тестовая строка 2n");
dos.close();
DataInputStream и DataOutputStream
При чтении и записи часто неудобно
бывает оперировать байтами (тип
byte[] и int)
Для более удобной работы с потоками
существуют указанные классы
Имеют методы для чтения и записи
данных различных типов:
writeInt, writeDouble, writeUTF и т.п.
Являются классами-обѐртками для
потоков, т.е. их конструкторы
принимают в качестве параметров уже
созданные потоки:
FileInputStream fis = new FileInputStream(inputFileName);
DataInputStream dis = new DataInputStream(fis);
Чтение и запись объектов
Механизм сериализации:
class User implements Serializable {
private String login;
public String passwd;
… геттеры/сеттеры
}
public class UserFrame extends javax.swing.JFrame {
ObjectInputStream ois;
ObjectOutputStream oos;
String fileName = "d:users.dat";
…
ois = new ObjectInputStream(new FileInputStream(fileName));
User u = (User)ois.readObject();
jTextField1.setText(u.getLogin());
jTextField2.setText(u.getPasswd());
ois.close();
…
oos = new ObjectOutputStream(new FileOutputStream(fileName));
User u = new User();
u.setLogin(jTextField1.getText());
Классы Reader и Writer
Абстрактные базовые классы потоков
для чтения/записи символьных данных
Д/З
Изучить презентацию и Лекцию № 15
Самостоятельно разобраться с классами
File и RandomAccessFile
1) создать программу решения квадратных
уравнений, кот. считывает 3 вещественных
числа из файла и записывает результат в
другой файл.
2) создать программу подсчѐта среднего
арифметического элементов массива.
Считывает из файла кол-во элементов и
сами элементы, записывает в другой файл
результат.
3) создать программу сохранения
информации о нескольких сотрудниках в
файл и извлечение этой информации.
Использовать поток ObjectOutputStream