• Serialize(). Сохраняет объектный граф в указанном потоке в виде последовательности байтов.
• Deserialize(). Преобразует сохраненную последовательность байтов в объектный граф.
Предположим, что мы создали экземпляр JamesBondCar, изменили в нем некоторые данные и хотим сохранить этот "шпиономобиль" в файле *.dat. Первой нашей задачей является создание самого файла *.dat. Это можно сделать с помощью создания экземпляра типа System.IO.FileStream (см. главу 16). Создайте экземпляр BinaryFormatter и передайте ему FileStream и объектный граф для сохранения.
using System.Runtime.Serialization.Formatters.Binary; using System.IO;
…
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.
Реконструкция объектов с помощью BinaryFormatter
Теперь предположим, что вы хотите прочитать сохранённые данные JamesBondCar из двоичного файла назад в объектную переменную. Программно открыв CarData.dat (с помощью метода OpenRead()), вызовите метод Deserialize() объекта BinaryFormatter. Метод Deserialize() возвращает общий тип System.Object, поэтому вам придется выполнить явное преобразование, как показано ниже.
static void Main(string[] args) {
…
// Чтение JamesBondCar из двоичного файла.
fStream = File.OpenRead("CarData.dat");
JamesBondCar carFromDisk = (JamesBondCar)binFormat.Deserialize(fStream);
Console.WriteLine("Может ли машина летать?: {0}", carFromDisk.canFly);
fStream.Close();
Console.ReadLine();
}
Обратите внимание на то, что при вызове Deserialize() методу передается производный от Stream тип, указывающий место хранения объектного графа (в данном случае это файловый поток). Так что проще уже некуда. По сути, сначала нужно обозначить атрибутом [Serializable] все классы, предназначенные для сохранения в потоке. После этого нужно использовать тип BinaryFormatter, чтобы передать объектный граф в двоичный поток и извлечь его оттуда. Вы можете увидеть двоичный образ, представляющий экземпляр JamesBondCar (рис. 17.2).
Рис. 17.2. Сериализация JamesBondCar с помощью BinaryFormatter
Сериализация объектов с помощью SoapFormatter
Следующим вариантом является тип SoapFormatter. Тип SoapFormatter сохраняет объектный граф в сообщении SOAP (Simple Object Access Protocol – простой протокол доступа к объектам), что делает этот вариант форматирования прекрасным выбором при передаче объектов средствами удаленного взаимодействия по протоколу HTTP. Если вы не знакомы со спецификациями SOAP, не волнуйтесь. В сущности, SOAP определяет стандартный процесс, с помощью которого можно вызывать методы не зависящим от платформы и ОС способом (мы рассмотрим SOAP чуть более подробно в последней главе этой книги при обсуждении Web-сервисов XML).
В предположении о том, что вы установили ссылку на компоновочный блок System.Runtime.Serialization.Formatters.Soap.dll, можно реализовать сохранение и восстановление JamesBondCar в формате сообщения SOAP с помощью замены BinaryFormatter на SoapFormatter. Рассмотрите следующий программный код, который выполняет сериализацию объекта в локальный файл с именем CarData.soap.
using System.Runtime.Serialization.Formatters.Soap;
…
static void Main(string[] args) {
…
// Сохранение объекта в файл CarData.soap в формате SOAP.
SoapFormatter soapFormat = new SoapFormatter();
fStream = new FileStream("CarData.soap", FileMode.Create, FileAccess.Write, FileShare.None);
soapFormat.Serialize(fStream, jbc);
fStream.Close();
Console.ReadLine();
}
Как и ранее, здесь просто используются Serialize() и Deserialize() для перемещения объектного графа в поток и восстановления его из потока. Если открыть полученный файл *.soap, вы увидите в нем элементы XML, представляющие значения JamesBondCar и взаимосвязи между объектами графа (с помощью лексем #ref). Рассмотрите следующий фрагмент XML-кода, соответствующий конечному результату (для краткости здесь опущены указания на пространства имен XML).
Читать дальше