Чтение онлайн

на главную - закладки

Жанры

Программирование на Java

Вязовик Н.А.

Шрифт:

Расширение стандартной сериализации

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

private void writeObject(

java.io.ObjectOutputStream out)

throws IOException;

private void readObject(

java.io.ObjectInputStream in)

throws IOException, ClassNotFoundException;

Если в классе объявлены такие методы, то при сериализации объекта для записи его состояния будет вызван writeObject, который должен сгенерировать последовательность байт и записать ее в поток out, полученный в качестве аргумента. При этом можно вызвать стандартный механизм записи объекта путем вызова метода

out.defaultWriteObject;

Этот метод запишет все не- transient и не- static поля в поток данных.

В свою очередь, при десериализации метод readObject должен считать данные из потока in (также полученного в качестве аргумента) и восстановить значения полей класса. При реализации этого метода можно обратиться к стандартному механизму с помощью метода:

in.defaultReadObject;

Этот метод считывает описание объекта из потока и присваивает значения соответствующих полей в текущем объекте.

Если же процедура сериализации в корне отличается от стандартной, то для таких классов предназначен альтернативный интерфейс java.io.Externalizable.

При использовании этого интерфейса в поток автоматически записывается только идентификация класса. Сохранить и восстановить всю информацию о состоянии экземпляра должен сам класс. Для этого в нем должны быть объявлены методы writeExternal и readExternal интерфейса Externalizable. Эти методы должны обеспечить сохранение состояния, описываемого полями самого класса и его суперкласса.

При восстановлении Externalizable -объекта экземпляр создается путем вызова конструктора без аргументов, после чего вызывается метод readExternal.

Метод writeExternal имеет сигнатуру:

void writeExternal(ObjectOutput out)

throws IOException;

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

void readExternal(ObjectInput in)

throws IOException,ClassNotFoundException;

эти значения должны быть считаны в том же самом порядке.

Классы Reader и Writer и их наследники

Рассмотренные классы – наследники InputStream и OutputStream – работают с байтовыми данными. Если с их помощью записывать или считывать текст, то сначала необходимо сопоставить каждому символу его числовой код. Такое соответствие называется кодировкой.

Известно, что Java использует кодировку Unicode, в которой символы представляются двухбайтовым кодом. Байтовые потоки зачастую работают с текстом упрощенно – они просто отбрасывают старший байт каждого символа. В реальных же приложениях могут использовать различные кодировки (даже для русского языка их существует несколько). Поэтому в версии Java 1.1 появился дополнительный набор классов, основывающийся на типах Reader и Writer. Их иерархия представлена на рис. 15.2.

Эта иерархия очень схожа с аналогичной для байтовых потоков InputStream и OutputStream. Главное отличие между ними – Reader и Writer работают с потоком символов ( char ). Только чтение массива символов в Reader описывается методом read(char[]), а запись в Writer – write(char[]).

В таблице 15.1 приведены соответствия классов для байтовых и символьных потоков.

Рис. 15.2. Иерархия классов Reader и Writer.

Таблица 15.1. Соответствие классов для байтовых и символьных потоков.

Байтовый поток

Символьный поток

InputStream

Reader

OutputStream

Writer

ByteArrayInputStream

CharArrayReader

ByteArrayOutputStream

CharArrayWriter

Нет аналога

InputStreamReader

Нет аналога

OutputStreamWriter

FileInputStream

FileReader

FileOutputStream

FileWriter

FilterInputStream

FilterReader

FilterOutputStream

FilterWriter

BufferedInputStream

BufferedReader

BufferedOutputStream

BufferedWriter

PrintStream

PrintWriter

DataInputStream

Нет аналога

DataOutputStream

Нет аналога

ObjectInputStream

Нет аналога

ObjectOutputStream

Нет аналога

PipedInputStream

PipedReader

PipedOutputStream

PipedWriter

StringBufferInputStream

StringReader

Нет аналога

StringWriter

LineNumberInputStream

LineNumberReader

PushBackInputStream

PushBackReader

SequenceInputStream

Нет аналога

Как видно из таблицы, различия крайне незначительны и предсказуемы.

Например, конечно же, отсутствует преобразование в символьное представление примитивных типов Java и объектов ( DataInput/Output, ObjectInput/Output ). Добавлены классы-мосты, преобразующие символьные потоки в байтовые: InputStreamReader и OutputStreamWriter. Именно на их основе реализованы FileReader и FileWriter. Метод available класса InputStream в классе Reader отсутствует, он заменен методом ready, возвращающим булевое значение, – готов ли поток к считыванию (то есть будет ли считывание произведено без блокирования).

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

String fileName = "d:\\file.txt";

//Строка, которая будет записана в файл

String data = "Some data to be written and read.\n";

try {

FileWriter fw = new FileWriter(fileName);

BufferedWriter bw = new BufferedWriter(fw);

System.out.println("Write some data to file: " + fileName);

// Несколько раз записать строку

for(int i=(int)(Math.random*10);--i>=0;)

bw.write(data);

bw.close;

// Считываем результат

FileReader fr = new FileReader(fileName);

BufferedReader br = new BufferedReader(fr);

String s = null;

int count = 0;

System.out.println("Read data from file: " + fileName);

// Считывать данные, отображая на экран

while((s=br.readLine)!=null)

System.out.println("row " + ++count + " read:" + s);

Поделиться:
Популярные книги

Черный Маг Императора 15

Герда Александр
15. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
фантастика: прочее
5.00
рейтинг книги
Черный Маг Императора 15

Кукловод

Злобин Михаил
2. О чем молчат могилы
Фантастика:
боевая фантастика
8.50
рейтинг книги
Кукловод

Простолюдин

Рокотов Алексей
1. Путь князя
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Простолюдин

Эпоха Опустошителя. Том II

Павлов Вел
2. Вечное Ристалище
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эпоха Опустошителя. Том II

Неудержимый. Книга VIII

Боярский Андрей
8. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
6.00
рейтинг книги
Неудержимый. Книга VIII

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Гримуар темного лорда VI

Грехов Тимофей
6. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.25
рейтинг книги
Гримуар темного лорда VI

Наша навсегда

Зайцева Мария
2. Наша
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Наша навсегда

Апокриф

Вайс Александр
10. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Апокриф

Инженер Петра Великого

Гросов Виктор
1. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Инженер Петра Великого

Гражданин тьмы

Афанасьев Анатолий Владимирович
Детективы:
боевики
5.00
рейтинг книги
Гражданин тьмы

Вечный. Книга IV

Рокотов Алексей
4. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга IV

Везунчик. Проводник

Бубела Олег Николаевич
3. Везунчик
Фантастика:
фэнтези
6.62
рейтинг книги
Везунчик. Проводник

Первый среди равных. Книга III

Бор Жорж
3. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
6.00
рейтинг книги
Первый среди равных. Книга III