Чтение онлайн

ЖАНРЫ

ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

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

Шрифт:

 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).

‹SOAP-ENV:Envelope xmlns:xsi="…"›

 ‹SOAP-ENV:Body›

‹a1:JamesBondCar id="ref-1" xmlns:a1="…"›

‹canFly›true‹/canFly›

‹canSubmerge›false‹/canSubmerge›

‹theRadio href="#"/›

‹isHatchBack›false‹/isHatchBack›

‹/a1:JamesBondCar›

‹a1:Radio id="ref-3" xmlns:a1="…"›

‹hasTweeters›true‹/hasTweeters›

‹hasSubWoofers›false‹/hasSubWoofers›

‹stationPresets href="#"/›

‹/a1:Radio›

‹SOAP-ENC:Array id="ref-4" SOAP-ENC:arrayType="xsd:dooble[3]"›

‹item›89.3‹/item›

‹item›105.1‹/item›

‹item›97.1‹/item›

‹/SOAP-ENC:Array›

 ‹/SOAP-ENV:Body›

 ‹/SOAP-ENV:Envelope›

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

Вдобавок к SOAP и двоичному формату, компоновочный блок System.Xml.dll предлагает третий формат, обеспечиваемый типом System.Xml.Serialization. XmlSerializer который может использоваться для сохранения состояния данного объекта в виде "чистого" XML в противоположность данным XML, упакованным в сообщении SOAP. Работа с этим типом немного отличается от работы с типами SoapFormatter и BinaryFormatter. Рассмотрим следующий программный код.

using Sуstem.Xml.Serialization;

static void Main(string[] args) {

 …

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

 XmlSerializer xmlFormat = new XmlSerializer(typeof(JamesBondCar), new Type[] { typeof(Radio), typeof(Car) });

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

 xmlFormat.Serialize(fStream, jbc);

 fStream.Close;

 …

}

Здесь главным отличием является то, что тип XmlSerializer требует указания информации о типе соответствующего элемента объектного графа. Обратите внимание на то, что первый аргумент конструктора XmlSerializer определяет корневой элемент XML-файла, а второй аргумент является массивом типов System.Type, содержащих метаданные подчиненных элементов. Если заглянуть в сгенерированный файл CarData.xml, вы увидите следующий XML-код (здесь он приводится в сокращенном виде).

Поделиться с друзьями: