Читайте также:
|
|
Объект сериализуется при помощи метода writeObject() келасса ObjectOutputStream и десериализуется методом readObject() класса ObjectInputStream. Эти классы являются стандартными байтовыми потоками. Они реализуют интерфейсы ObjectOutput и ObjectInput, являющиеся дочерними для интерфейсов DataOutput и DataInput. Это означает, что для чтения и записи примитивных значений они используют одни и те же методы. Объект сериализуется путем передачи его методу writeObject() класса ObjectOutputStream и выводит значения всех полей, включая закрытые поля и поля, унаследованные от родительских классов.
При десериализации объект считывается из потока данных посредством вызова метода readObject() класса ObjectInputStream, который восстанавливает объект в его состояние до сериализации. Если объект ссылается на другие объекты, они также рекурсивно десериализуются.
Пример 5.1. Демонстрация основ сериализации, определяющих методов, сохраняющих в файле и возвращающих из него любые сериализуемые объекты.
package Serializer.java;import java.io.*; /** * Класс определяет утилиты, используемые для Java-сериализации. **/public class Serializer { /** * сериализация объектов (и объектов по ссылке) * с последующим сохранением в файле f. **/ static void store(Serializable o, File f) throws IOException { ObjectOutputStream out = // класс для сериализации new ObjectOutputStream(new FileOutputStream(f)); out.writeObject(o); // метод сериализации иерархии объектов out.close(); } /** * десериализация файла f и возврат результирующего объекта **/ static Object load(File f) throws IOException, ClassNotFoundException { ObjectInputStream in = // класс десериализации new ObjectInputStream(new FileInputStream(f)); return in.readObject(); // метод десериализации иерархии объектов } /** * сериализация и десериализация иерархии объектов **/ static Object deepclone(final Serializable o) throws IOException, ClassNotFoundException { // создание потоков. // запись и чтение байтов из потоков. final PipedOutputStream pipeout = new PipedOutputStream(); PipedInputStream pipein = new PipedInputStream(pipeout); // создание потока исполнения для сериализации // и записи байтов в PipedOutputStream Thread writer = new Thread() { public void run() { ObjectOutputStream out = null; try { out = new ObjectOutputStream(pipeout); out.writeObject(o); } catch(IOException e) {} finally { try { out.close(); } catch (Exception e) {} } } }; writer.start(); // запуск потока исполнения на сериализацию и запись // ериализуем в потоке данные из потока ввода // полученный поток будет клоном оригинала. ObjectInputStream in = new ObjectInputStream(pipein); return in.readObject(); } /** * сериализуемая структура данных **/ public static class DataStructure implements Serializable { String message; int[] data; DataStructure other; public String toString() { String s = message; for(int i = 0; i < data.length; i++) s += " " + data[i]; if (other!= null) s += "\n\t" + other.toString(); return s; } } /** класс метода main() для проверки работы */ public static class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { // создание иерархии объектов DataStructure ds = new DataStructure(); ds.message = "hello world"; ds.data = new int[] { 1, 2, 3, 4 }; ds.other = new DataStructure(); ds.other.message = "nested structure"; ds.other.data = new int[] { 9, 8, 7 }; // отображение иерархии System.out.println("Original data structure: " + ds); // вывод в файл File f = new File("datastructure.ser"); System.out.println("сохранить в файле..."); Serializer.store(ds, f); // считывание и отображение из файла ds = (DataStructure) Serializer.load(f); System.out.println("считано из файла: " + ds); // создание и отображение клона. DataStructure ds2 = (DataStructure) Serializer.deepclone(ds); ds.other.message = null; ds.other.data = null; // Change original System.out.println("Deep clone: " + ds2); } }}
Пример 5.2. Использует класс, реализующий динамический массив целых чисел, методы writeObject() и readObject() выполняют дополнительную обработку данных до и после сериализации.
package IntList.java;import java.io.*; /** * класс, реализующий динамический массив целых чисел**/public class IntList implements Serializable { protected int[] data = new int[8]; // массив для хранения чисел. protected transient int size = 0; // индекс следующего элемента массива /** возвращение элемента массива */ public int get(int index) throws ArrayIndexOutOfBoundsException { if (index >= size) throw new ArrayIndexOutOfBoundsException(index); else return data[index]; } /** к массиву добавляется новое число и его размер увеличивается */ public void add(int x) { if (data.length==size) resize(data.length*2); // увеличение размера. data[size++] = x; // сохранить значение. } /** метод для динамического изменения размера массива */ protected void resize(int newsize) { int[] newdata = new int[newsize]; // новый массив System.arraycopy(data, 0, newdata, 0, size); // копирование элементов data = newdata; // замена старого массива } /** перед сериализацией удаляем неиспользуемые элементы массива */ private void writeObject(ObjectOutputStream out) throws IOException { if (data.length > size) resize(size); // сжатие массива. out.defaultWriteObject(); // запись массива. } /** вычисление поля size после десериализации */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); // считывание массива. size = data.length; // восстановление значений. } /** * проверка содержимого объектов **/ public boolean equals(Object o) { if (!(o instanceof IntList)) return false; IntList that = (IntList) o; if (this.size!= that.size) return false; for(int i = 0; i < this.size; i++) if (this.data[i]!= that.data[i]) return false; return true; } /** Метод main() для отображения результатов */ public static void main(String[] args) throws Exception { IntList list = new IntList(); for(int i = 0; i < 100; i++) list.add((int)(Math.random()*40000)); IntList copy = (IntList)Serializer.deepclone(list); if (list.equals(copy)) System.out.println("equal copies"); Serializer.store(list, new File("intlist.ser")); }}
Дата добавления: 2015-09-11; просмотров: 72 | Поможем написать вашу работу | Нарушение авторских прав |