Spec-Zone .ru
спецификации, руководства, описания, API
СОДЕРЖАНИЕ | ПРЕДЫДУЩИЙ | NEXT Спецификация Сериализации Объекта Java
версия 6.0

Объектный Потоковый Протокол Сериализации






ГЛАВА 6

Темы:


6.1 Краткий обзор

Потоковый формат удовлетворяет следующие цели проекта:


6.2 Потоковые Элементы

Базовая структура необходима, чтобы представить объекты в потоке. Каждый атрибут объекта должен быть представлен: его классы, его поля, и записанные данные и позже читают class специфичные методы. Представление объектов в потоке может быть описано с грамматикой. Есть специальные представления для нулевых объектов, новых объектов, классов, массивов, строк, и обратных ссылок на любой объект уже в потоке. Каждый объект, записанный потоку, присваивается дескриптор, который используется, чтобы вернуться к объекту. Дескрипторы присваиваются, последовательно запускаясь с 0x7E0000. Дескрипторы перезапускают в 0x7E0000, когда поток сбрасывается.

Объект class представляется следующим:

ObjectStreamClass объект для Класса, который не является динамическим прокси class, представляется следующим:

ObjectStreamClass объект для динамического прокси class представляется следующим:

Представление String объекты состоят из информации о длине, сопровождаемой содержанием строки, закодированной в измененном UTF-8. Измененное кодирование UTF-8 является тем же самым как использующийся в виртуальной машине Java и в java.io.DataInput и DataOutput интерфейсы; это отличается от стандартного UTF-8 в представлении дополнительных символов и нулевого символа. Форма информации о длине зависит от длины строки в измененном кодировании UTF-8. Если измененное кодирование UTF-8 данного String меньше чем 65536 байтов в длине, длина пишется как 2 байта, представляющие 16-разрядное целое число без знака. Запускаясь с Java 2 платформы, Standard Edition, v1.3, если длина строки в измененном кодировании UTF-8 составляет 65536 байтов или больше, длина пишется в 8 байтах, представляющих подписанное 64-разрядное целое число. typecode предшествование String в сериализации поток указывает, какой формат использовался, чтобы записать String.

Массивы представляются следующим:

Перечислимые константы представляются следующим:

Новые объекты в потоке представляются следующим:

Все примитивные данные, записанные классами, буферизуются и обертываются в блочные записи данных, независимо если данные пишутся потоку в пределах a writeObject метод или записанный непосредственно потоку снаружи a writeObject метод. Эти данные могут только быть считаны соответствием readObject методы или быть считанным непосредственно из потока. Объекты, записанные writeObject метод, оконечный любая предыдущая блочная запись данных и, пишется или как регулярные объекты или как нулевые или обратные ссылки, как соответствующий. Блочные записи данных позволяют восстановлению после ошибки отбрасывать любые дополнительные данные. Когда вызвано изнутри class, поток может отбросить любые данные или объекты до endBlockData.


6.3 Потоковые Версии Протокола

Было необходимо произвести изменение в потоковом формате сериализации в JDK 1.2, который не является назад совместимым со всеми незначительными выпусками JDK 1.1. Чтобы предусмотреть случаи, где назад совместимость требуется, возможность была добавлена, чтобы указать что PROTOCOL_VERSION использовать при записи потока сериализации. Метод ObjectOutputStream.useProtocolVersion берет в качестве параметра версию протокола, чтобы использовать, чтобы записать поток сериализации.

Потоковые Версии Протокола следующие:

JDK 1.2 значения по умолчанию к записи PROTOCOL_VERSION_2.

JDK 1.1 значения по умолчанию к записи PROTOCOL_VERSION_1.

JDK 1.1.7 и больше может считать обе версии.

Выпуски до JDK 1.1.7 могут только читать PROTOCOL_VERSION_1.


6.4 Грамматика для Потокового Формата

Таблица ниже содержит грамматику для потокового формата. Нетерминальные символы показывают курсивом. Терминальные символы в фиксированном шрифте width. Определения нетерминалов сопровождаются ":". Определение сопровождается одной или более альтернативами, каждым на отдельной строке. Следующая таблица описывает нотацию:

Нотация
Значение

(тип данных)

Этому маркеру определили тип данных, такой как байт.

маркер [n]

Предопределенное число возникновений маркера, который является массивом.

x0001

Литеральное значение, выраженное в шестнадцатеричном. Число шестнадцатеричных цифр отражает размер значения.

<xxx>

Значение, считанное из потока, используемого, чтобы указать на длину массива.

Отметьте, что символ (utf) используется, чтобы назвать строку записанной, используя 2-байтовую информацию о длине, и (долго-utf) используется, чтобы назвать строку записанной, используя 8-байтовую информацию о длине. Для получения дополнительной информации обратитесь к Разделу 6.2, "Потоковые Элементы".

6.4.1 Правила Грамматики

Сериализованный поток представляется любым потоком, удовлетворяющим потоковое правило.

stream:
  magic version contents

contents:
  content
  contents content

content:
  object
  blockdata

object:
  newObject
  newClass
  newArray
  newString
  newEnum
  newClassDesc
  prevObject
  nullReference
  exception
  TC_RESET

newClass:
  TC_CLASS classDesc newHandle

classDesc:
  newClassDesc
  nullReference
  (ClassDesc)prevObject      // an object required to be of type
                             // ClassDesc

superClassDesc:
  classDesc

newClassDesc:
  TC_CLASSDESC className serialVersionUID newHandle classDescInfo
  TC_PROXYCLASSDESC newHandle proxyClassDescInfo
classDescInfo:
  classDescFlags fields classAnnotation superClassDesc 

className:
  (utf)

serialVersionUID:
  (long)

classDescFlags:
  (byte)                  // Defined in Terminal Symbols and
                            // Constants

proxyClassDescInfo:
  (int)<count> proxyInterfaceName[count] classAnnotation
      superClassDesc
proxyInterfaceName:
  (utf)
fields:
  (short)<count>  fieldDesc[count]

fieldDesc:
  primitiveDesc
  objectDesc

primitiveDesc:
  prim_typecode fieldName

objectDesc:
  obj_typecode fieldName className1

fieldName:
  (utf)

className1:
  (String)object             // String containing the field's type,
                             // in field descriptor format
classAnnotation:
  endBlockData
  contents endBlockData      // contents written by annotateClass

prim_typecode:
  `B'       // byte
  `C'       // char
  `D'       // double
  `F'       // float
  `I'       // integer
  `J'       // long
  `S'       // short
  `Z'       // boolean

obj_typecode:
  `[`   // array
  `L'       // object

newArray:
  TC_ARRAY classDesc newHandle (int)<size> values[size]

newObject:
  TC_OBJECT classDesc newHandle classdata[]  // data for each class

classdata:
  nowrclass                 // SC_SERIALIZABLE & classDescFlag &&
                            // !(SC_WRITE_METHOD & classDescFlags)
  wrclass objectAnnotation  // SC_SERIALIZABLE & classDescFlag &&
                            // SC_WRITE_METHOD & classDescFlags
  externalContents          // SC_EXTERNALIZABLE & classDescFlag &&
                            // !(SC_BLOCKDATA  & classDescFlags
  objectAnnotation          // SC_EXTERNALIZABLE & classDescFlag&& 
                            // SC_BLOCKDATA & classDescFlags

nowrclass:
  values                    // fields in order of class descriptor

wrclass:
  nowrclass

objectAnnotation:
  endBlockData
  contents endBlockData     // contents written by writeObject
                            // or writeExternal PROTOCOL_VERSION_2.

blockdata:
  blockdatashort
  blockdatalong

blockdatashort:
  TC_BLOCKDATA (unsigned byte)<size> (byte)[size]

blockdatalong:
  TC_BLOCKDATALONG (int)<size> (byte)[size]

endBlockData   :
  TC_ENDBLOCKDATA

externalContent:          // Only parseable by readExternal
  ( bytes)                // primitive data
    object

externalContents:         // externalContent written by 
  externalContent         // writeExternal in PROTOCOL_VERSION_1.
  externalContents externalContent

newString:
  TC_STRING newHandle (utf)
  TC_LONGSTRING newHandle (long-utf)

newEnum:
  TC_ENUM classDesc newHandle enumConstantName
enumConstantName:
  (String)object
prevObject
  TC_REFERENCE (int)handle

nullReference
  TC_NULL

exception:
  TC_EXCEPTION reset (Throwable)object         reset 

magic:
  STREAM_MAGIC

version
  STREAM_VERSION

values:          // The size and types are described by the
                 // classDesc for the current object

newHandle:       // The next number in sequence is assigned
                 // to the object being serialized or deserialized

reset:           // The set of known objects is discarded
                 // so the objects of the exception do not
                 // overlap with the previously sent objects 
                 // or with objects that may be sent after 
                 // the exception


6.4.2 Терминальные Символы и Константы

Следующие символы в java.io.ObjectStreamConstants определите терминальные и постоянные величины, ожидаемые в потоке.

    final static short STREAM_MAGIC = (short)0xaced;
    final static short STREAM_VERSION = 5;
    final static byte TC_NULL = (byte)0x70;
    final static byte TC_REFERENCE = (byte)0x71;
    final static byte TC_CLASSDESC = (byte)0x72;
    final static byte TC_OBJECT = (byte)0x73;
    final static byte TC_STRING = (byte)0x74;
    final static byte TC_ARRAY = (byte)0x75;
    final static byte TC_CLASS = (byte)0x76;
    final static byte TC_BLOCKDATA = (byte)0x77;
    final static byte TC_ENDBLOCKDATA = (byte)0x78;
    final static byte TC_RESET = (byte)0x79;
    final static byte TC_BLOCKDATALONG = (byte)0x7A;
    final static byte TC_EXCEPTION = (byte)0x7B;
    final static byte TC_LONGSTRING = (byte) 0x7C;
    final static byte TC_PROXYCLASSDESC = (byte) 0x7D;
    final static byte TC_ENUM = (byte) 0x7E;
    final static  int   baseWireHandle = 0x7E0000;
Байт флага classDescFlags может включать значения

    final static byte SC_WRITE_METHOD = 0x01; //if SC_SERIALIZABLE
     final static byte SC_BLOCK_DATA = 0x08;    //if SC_EXTERNALIZABLE
    final static byte SC_SERIALIZABLE = 0x02;
    final static byte SC_EXTERNALIZABLE = 0x04;
    final static byte SC_ENUM = 0x10;
SC_WRITE_METHOD флага устанавливается, если у Сериализуемого class, пишущий поток был a writeObject метод, который, возможно, записал дополнительные данные в поток. В этом случае маркер TC_ENDBLOCKDATA, как всегда ожидают, завершит данные для того class.

Флаг SC_BLOCKDATA устанавливается если Externalizable class пишется в потоковое использование STREAM_PROTOCOL_2. По умолчанию это - протокол, используемый, чтобы записать Externalizable объекты в поток в JDK 1.2. JDK 1.1 записи STREAM_PROTOCOL_1.

SC_SERIALIZABLE флага устанавливается, если class, который записал расширенный поток java.io.Serializable но нет java.io.Externalizable, class, читая поток должен также расшириться java.io.Serializable и механизм сериализации значения по умолчанию должен использоваться.

SC_EXTERNALIZABLE флага устанавливается, если class, который записал расширенный поток java.io.Externalizable, class, читая данные должен также расшириться Externalizable и данные будут считаны, используя writeExternal и readExternal методы.

SC_ENUM флага устанавливается, если class, который записал поток, был перечислимым типом. Соответствующий class получателя должен также быть перечислимым типом. Данные для констант перечислимого типа будут записаны и считаны как описано в Разделе 1.12, "Сериализация Перечислимых Констант".


Пример

Рассмотрите случай исходного class и двух экземпляров в связанном списке:

class List implements java.io.Serializable {
    int value;
    List next;
    public static void main(String[] args) {
        try {
            List list1 = new List();
            List list2 = new List();
            list1.value = 17;
            list1.next = list2;
            list2.value = 19;
            list2.next = null;

            ByteArrayOutputStream o = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(o);
            out.writeObject(list1);
            out.writeObject(list2);
            out.flush();
            ...
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
Получающийся поток содержит:

00: ac ed 00 05 73 72 00 04 4c 69 73 74 69 c8 8a 15 >....sr..Listi...<
10: 40 16 ae 68 02 00 02 49 00 05 76 61 6c 75 65 4c >Z......I..valueL<
20: 00 04 6e 65 78 74 74 00 06 4c 4c 69 73 74 3b 78 >..nextt..LList;x<
30: 70 00 00 00 11 73 71 00 7e 00 00 00 00 00 13 70 >p....sq.~......p<
40: 71 00 7e 00 03                                  >q.~..<


СОДЕРЖАНИЕ | ПРЕДЫДУЩИЙ | NEXT
Авторское право © 2005, 2010, Oracle и/или его филиалы. Все права защищены.