[ Home ]
[ Java... in Russian!]



Understanding Java Serialization

by Govind Seshadri


Введение в сериализацию* в яве

Говинд Сэшадри

Перевод 1997 (C) Алексей Гузеев

* Сериализация (serialization) - от англ. serial - последовательный.

Сохранение информации - базовая необходимость

Любое сколько-нибудь полезное приложение требует сохранения информации между запусками. Если вас интересует есть ли простой способ сохранять объекты между запусками в Яве, вы безусловно выбрали правильное время для решения этого вопроса. JDK 1.1 предоставляет программисту механизм, называемый Object Serialization для решения одной из неприятный проблем сохранения объектов. Используя сериализацию, вы можете без затруднений записать объекты в файл, или послать их на распределённые Ява-сервера используя Remote Method Invocation (RMI).

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

А для чего же тогда JDBC?

Некоторые могут спросить: "А разве JDBC не позволяет сохранять информацию?". Да, это так, но это похоже на починку часов кувалдой. JDBC - это достаточно сложный интерфейс, который позволяет интегрировать мощные реляционные базы данных в ваши программы на яве. Если ваше приложение - относительно небольшое и не входит в какой-либо крупный пакет, с необходимостью хранение порядка нескольких сотен записей, использование баз Oracle или Sybase как хранилища - это чистое самоубийство. Задача может быть решена значительно проще если хранить объекты в файле, используя сериализацию.

Реляционные базы данных могут вам не подойти и в том случае, если вам необхомо хранить исключительно большие объёмы информации, и если если у вас много конечных пользователей требующих систему с высокой пропускной способностью. Учитывайте, что каждый раз, когда вам требуется записать/считать из реляционной базы данных, необходимо отображать информацию, хранимую в двумерных таблицах в объекты явы. Это отображение не только уменьшает продуктивность программиста, но и снижает общее быстродействие системы. Идеальное решение для больших, критичных приложений было-бы использование объектных баз данных. Хотя переучиваться достаточно сложно, это с лихвой окупится в будущем.

Под капотом

Давайте попробуем разобраться в механизме работы сериализации на следующем примере:
Листинг 1. Person.java

public class Person implements java.io.Serializable {

  int id;
  String name;
  String addr;

  public Person (int key, String n, String a) {
    id=key;
    name=n;
    addr=a;
  }
}
В классе Person нет ничего необычного, исключая то что он реализует интерфейс Serializable. Для того, чтобы объект мог быть преобразован в поток при сериализации необходимо реализовать интерфейс Serializable.
Листинг 2. Rolodex.java

class Rolodex implements java.io.Serializable {

  Person[] data=new Person[5];
      
  public Rolodex () {
    data[0]=new Person(100, "Lazy Larry",  "123 Easy Drive");
    data[1]=new Person(101, "Happy Harry", "30 Sunset Ave" );
    data[2]=new Person(102, "Big Bessie",  "11 Market Way" );
    data[3]=new Person(103, "Guitar Man",  "461 Ocean Blvd");
    data[4]=new Person(104, "Java Joe",    "1 Hacker Ave"  );
  }

  public void display () {
    for (int i=0; i<5; i++) {
      System.out.println("ID: "+data[i].id);
      System.out.println("NAME: "+data[i].name);
      System.out.println("ADDR: "+data[i].addr);
    }
  }
}
Класс Rolodex, показынный в листинге 2, также реализует интерфейс Serializable. Этот класс, по существу - массив объектов Person, инициализированный некоторыми значениями. А теперь мы можем заняться непосредственно сохранением и чтением объектов, используя сериализацию.
Листинг 3. RoloWrite.java

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class RoloWrite {
              
  public static void main (String[] args) {
    Rolodex rolodex=new Rolodex();
    try {
      FileOutputStream fo=new FileOutputStream("rolodata");
      ObjectOutputStream serial=new ObjectOutputStream(fo);
      serial.writeObject(rolodex);
      serial.flush();
    } catch (Exception ex) {
      System.out.println("Ошибка при сериализации объекта");
    }
  }
}
Класс RoloWrite, показанный в листинге 3, демонстрирует насколько просто объекты явы могут быть записаны в файл, после преобразования их в поток байтов. Прежде всего мы создаём объект класса Rolodex, который мы собираемся сохранить. Объект класса FileOutputStream создан потому, что мы должны присоединить наш ObjectOutputStream к чему-нибудь. Объект класса ObjectOutputStream содержит теперь всю необходимую функциональность для сериализации любого объекта и записи его в поток.

Теперь, чтобы записать наш объект класса Rolodex в поток, нужно всего лишь вызвать метод writeObject класса ObjectOutputStream: serial.writeObject(rolodex);.

Заметьте, что мы совершенно не изменили класс объекта чтобы сделать его сохраняемым. Мы просто записываем объект в поток, как есть!

Листинг 4 RoloRead.java

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class RoloRead {
                 
  public static void main (String[] args) {
    Rolodex rolodex=null;
    try {
      FileInputStream fi=new FileInputStream("rolodata");
      ObjectInputStream serial=new ObjectInputStream(fi);
      rolodex=(Rolodex)serial.readObject();
      rolodex.display();
    } catch (Exception ex) {
      System.out.println("Ошибка при сериализации объекта");
    }
  }
}
Класс RoloRead, показанный в листинге 4, прежде всго открывает поток к файлу данных используя класс FileInputStream. Присоединив этот поток к объекту класса ObjectInputStream, мы готовы читать объект, используя метод readObject. Обратите внимание, что объект, который возвращает метод readObject необходимо преобразовать в ваш результатирующий класс - Rolodex - ява не будет делать это за вас автоматически. При вызове метода display полученного объекта класса Rolodex на экране появлятся содержимое этого объекта.

RoloWrite.java и RoloRead.java компилируются обычным образом. Создайте образ объекта запуском RoloWrite, а затем запустите RoloWrite. Вы увидите следующий вывод:

	ID: 100
	NAME: Lazy Larry
	ADDR: 123 Easy Drive
	ID: 101 
	NAME: Happy Harry
	ADDR: 30 Sunset Ave
	ID: 102
	NAME: Big Bessie 
	ADDR: 11 Markey Way
	ID: 103 
	NAME: Guitar Man
	ADDR: 461 Ocean Blvd
	ID: 104
	NAME: Java Joe
	ADDR: 1 Hacker Ave

Один механизм не решит все задачи

Хотя сериализация реализует аккуратный и простой интерфейс для сохранения объектов, она лучше подходит для приложений которые используют только небольшое количество данных, к которым не нужен одновременный конкурентный доступ. Так как сериализация записывает/считывает целые объекты после преоразования их в поток байтов, производителььность системы ухудшается если ваши объекты больше чем, скажем, мегабайт. По той же причине снижается производительность системы если ваша программа интенсивно выполняет операции чтения или записи. Необходимо отметить, что сериализация не выполняет никаких специальных возможностей баз данных таких как file locking, record locking, commit, rollback и т.д. По этой причине сериализация может не подойти к приложениям, в которых надёжность очень существенна.


О авторе...

Говинд Сэшадри воглавляет отдел явы в MGIC Investment Corporation. Его основные области интереса: крупномасштабные клиент-сервер ява-системы, защита в сети и электронный бизнес. Говинд имеет степени бакалавра и мастера (профессора?) информатики. Вы можете написать ему на Govind_Seshadri@mgic.com
© 1997 Javology
Понравилась ли вам статья? Как вы оцениваете качество перевода? Что вы хотите предложить для дальнейшего перевода? Пишите! Ваши отзывы очень важны для меня.
[ Home ]
[ Java... in Russian!]




This page hosted by Get your own Free Home Page
1