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

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

Жанры

Программирование на 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);

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

ЖЛ 9

Шелег Дмитрий Витальевич
9. Живой лёд
Фантастика:
фэнтези
боевая фантастика
5.00
рейтинг книги
ЖЛ 9

Тринадцатый VII

NikL
7. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый VII

Система Возвышения. (цикл 1-8) - Николай Раздоров

Раздоров Николай
Система Возвышения
Фантастика:
боевая фантастика
4.65
рейтинг книги
Система Возвышения. (цикл 1-8) - Николай Раздоров

Прапорщик. Назад в СССР. Книга 7

Гаусс Максим
7. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прапорщик. Назад в СССР. Книга 7

Старшеклассник без клана. Апелляция кибер аутсайдера

Афанасьев Семен
1. Старшеклассник без клана. Апелляция аутсайдера
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Старшеклассник без клана. Апелляция кибер аутсайдера

Лейб-хирург

Дроздов Анатолий Федорович
2. Зауряд-врач
Фантастика:
альтернативная история
7.34
рейтинг книги
Лейб-хирург

Гранит науки. Том 3

Зот Бакалавр
3. Героями не становятся, ими умирают
Фантастика:
фэнтези
боевая фантастика
5.00
рейтинг книги
Гранит науки. Том 3

Искатель 7

Шиленко Сергей
7. Валинор
Фантастика:
рпг
фэнтези
попаданцы
гаремник
5.00
рейтинг книги
Искатель 7

Локки 9. Потомок бога

Решетов Евгений Валерьевич
9. Локки
Фантастика:
фэнтези
попаданцы
героическая фантастика
боевая фантастика
5.00
рейтинг книги
Локки 9. Потомок бога

Барон переписывает правила

Ренгач Евгений
10. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Барон переписывает правила

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

Гросов Виктор
5. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
фэнтези
4.75
рейтинг книги
Инженер Петра Великого 5

Я — Легион

Злобин Михаил
3. О чем молчат могилы
Фантастика:
боевая фантастика
7.88
рейтинг книги
Я — Легион

Лекарь

Щепетнов Евгений Владимирович
1. Истринский цикл
Фантастика:
фэнтези
8.24
рейтинг книги
Лекарь

Двойник короля 17

Скабер Артемий
17. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 17