Читать «ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание» онлайн - страница 401

Эндрю Троелсен

Но SoapFormatter и XmlSerializer, с другой стороны, не пытаются сохранить тип абсолютно точно, поэтому они не записывают абсолютные имена типов и компоновочных блоков, а сохраняют только открытые поля данных и открытые свойства. На первый взгляд, это кажется ограничением, но реальная причина этого скрывается в открытой природе представления данных XML. Если вы хотите сохранить объектные графы так, чтобы они могли использоваться в любой операционной системе (Windows XP, ОС Маc X, различные вариации *nix), в рамках любого каркаса приложений (.NET. J2EE, COM и т.д.) и любом языке программирования, нет необходимости поддерживать абсолютную точность, поскольку у вас нет гарантии, что все возможные получатели смогут понять типы данных, специфичные для .NET. В этом случае идеальным выбором являются SoapFormatter и XmlSerializer, гарантирующие наиболее широкую доступность сохраненного объектного графа.

Сериализация объектов с помощью BinaryFormatter

Чтобы показать, как сохранить экземпляр JamesBondCar в физическом файле, давайте используем тип BinaryFormatter. Подчеркнем снова, что двумя ключевыми методами типа BinaryFormatter являются Serialize() и Deserialize().

• Serialize(). Сохраняет объектный граф в указанном потоке в виде последовательности байтов.

• Deserialize(). Преобразует сохраненную последовательность байтов в объектный граф.

Предположим, что мы создали экземпляр JamesBondCar, изменили в нем некоторые данные и хотим сохранить этот "шпиономобиль" в файле *.dat. Первой нашей задачей является создание самого файла *.dat. Это можно сделать с помощью создания экземпляра типа System.IO.FileStream (см. главу 16). Создайте экземпляр BinaryFormatter и передайте ему FileStream и объектный граф для сохранения.

 …

 static void Main (string[] args) {

 Console.WriteLine("*** Забавы с сериализацией объектов ***\n");

 // Создание JamesBondCar и установка данных состояния.

 JamesBondCar jbc = new JamesBondCar();

 jbc.canFly = true;

 jbc.canSubmerge = false;

 jbc.theRadio.statio.nPresets = new double[]{89.3, 105.1, 97.1};

 jbc.theRadio.hasTweeters = true;

 // Сохранение объекта в файл CarData.dat в двоичном формате.

 BinaryFormatter binFormat = new BinaryFormatter();

 Stream fStream = new FileStream("CarData.dat", FileMode.Create, FileAccess.Write, FileShare.None);

 binFormat.Serialize(fStream, jbc);

 fStream.Close();

 Console.ReadLine();

}

Как видите, метод BinaryFormatter.Serialize() отвечает за компоновку объектного графа и передачу соответствующей последовательности байтов некоторому типу, производному от Stream. В данном случае таким потоком является физический файл. Однако можно выполнять сериализацию объектных типов в любой производный от Stream тип, например в память, поскольку MemoryStream тоже является потомком типа Stream.