BinaryFormatter и SoapFormatter

54

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

Предположим, что после создания экземпляра JamesBondCar и модификации некоторых данных состояния требуется сохранить этот экземпляр в файле *.dat. Первая задача — создание самого файла *.dat. Для этого можно создать экземпляр типа System.IO.FileStream. Затем следует создать экземпляр BinaryFormatter и передать ему FileStream и граф объектов для сохранения. Взгляните на следующий метод Main():

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Serialize
{
    class Program
    {
        static void Main()
        {
            JamesBondClass jbc = new JamesBondClass();
            jbc.canFly = true;
            jbc.canSubmerge = false;
            jbc.theRadio.stationPresets = new double[] { 89.3, 105.1, 97.1 };
            jbc.theRadio.hasTweeters = true;
            // Сохранить объект в указанном файле в двоичном формате
            SaveBinaryFormat(jbc, "carData.dat");
            Console.ReadLine();
            
        }

        static void SaveBinaryFormat(object objGraph, string fileName)
        {
            BinaryFormatter binFormat = new BinaryFormatter();
            using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                binFormat.Serialize(fStream, objGraph);
            }
            Console.WriteLine("--> Сохранение объекта в Binary format");
        }
    }
...

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

После выполнения программы можно просмотреть содержимое файла carData.dat, представляющее этот экземпляр JamesBondCar, в папке bin\Debug текущего проекта. На рисунке показан этот файл, открытый в Visual Studio 2010:

Бинарная сериализация

Теперь предположим, что необходимо прочитать сохраненный объект JamesBondCar из двоичного файла обратно в объектную переменную. После открытия файла carData.dat (методом File.OpenRead()) просто вызовите метод Deserialize() класса BinaryFormatter. Имейте в виду, что Deserialize() возвращает объект общего типа System.Object, так что понадобится применить явное приведение, как показано ниже:

static void LoadFromBinaryFile(string fileName)
{
     BinaryFormatter binFormat = new BinaryFormatter();

     using (Stream fStream = File.OpenRead(fileName))
     {
          JamesBondClass carFromDisk =
               (JamesBondClass)binFormat.Deserialize(fStream);
          Console.WriteLine(carFromDisk.canFly);
     }
}

Обратите внимание, что при вызове Deserialize() ему передается тип-наследник Stream, представляющий местоположение сохраненного графа объектов. Приведя возвращенный объект к правильному типу, вы получаете объект в том состоянии, в каком он был на момент сохранения.

Следующий форматер, которым мы воспользуемся, будет SoapFormatter, сериализующий данные в подходящем конверте SOAP. Протокол SOAP (Simple Object Access Protocol — простой протокол доступа к объектам) определяет стандартный процесс вызова методов в независящей от платформы и операционной системы манере.

Предполагая, что ссылка на сборку System.Runtime.Serialization.Formatters.Soap.dll установлена, а пространство имен System.Runtime.Serialization.Formatters.Soap импортировано, для сохранения и извлечения JamesBondCar в виде сообщения SOAP можно просто заменить в предыдущем примере все вхождения BinaryFormatter на SoapFormatter. Ниже показан новый метод класса Program, который сериализует объект в локальный файл:

static void SoapWriteFile(object objGraph, string fileName)
    {
            SoapFormatter soapFormatter = new SoapFormatter();
            using (Stream fStream = new FileStream(fileName, 
                FileMode.Create, FileAccess.Write, FileShare.None))
            {
                soapFormatter.Serialize(fStream, objGraph);
            }
            Console.WriteLine("--> Сохранение объекта в SOAP-формат");
    }
Сериализация с помощью SoapFormatter
Пройди тесты
Лучший чат для C# программистов