Сохранение и восстановление объектов
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Сохранение объектов представляет собой определенную проблему. Связано это с тем, что обычно переменные объекта являются недоступными в программе. Для решения этой проблемы создано пространство имен System.Runtime.Serialization с классами, используемыми для сериализации и десериализации объектов.

 

Сериализация — это процесс преобразования объекта или графа объектов в линейную последовательность байтов для сохранения с помощью потока.

Десериализация — это процесс изъятия сохраненных сведений и создания из них объектов.

 

Для того чтобы объекты можно было сериализовать, его класс должен быть помечен атрибутом [Serializable].

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

 

Для сериализации объекта нужно выполнить следующие шаги:

• Пометить сериализуемый класс атрибутом [Serializable].

• Создать байтовый поток.

• Создать объект класса BinaryFormatter, управляющий сериализацией.

• Вызвать метод Serialize() этого объекта для выполнения сериализации.

 

 Для десериализации объектов нужно вместо метода Serialize() выполнить метод Deserialize() и привести воостанавливаемые объекты к требуемому типу.

 

// Сохранение объектов

using System;

using System.IO;

using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary;

 

[Serializable]

class Customer

{

private int      CustomerNumber;            // N покупателя

private string CustomerName;        // Имя покупателя

private string CustomerCountry;                // Страна

 

public Customer (int Number, string Name, string Country)

{

   this.CustomerNumber = Number;

   this.CustomerName = Name;

   this.CustomerCountry = Country;

}

 

public void WriteCustomer()

{

   Console.WriteLine("Customer Number: " + CustomerNumber);

   Console.WriteLine("Customer Name: " + CustomerName);

   Console.WriteLine("Customer Country: " + CustomerCountry);

}

}

class SaveObj

{

public static void Main()

{

   FileStream fs;

 

   Customer Customer1 = new Customer (1, "Aлен Дилон", "Франция");

   Customer Customer2 = new Customer (2, "Иванов", "Россия");

 

   Customer1.WriteCustomer();

   Customer2.WriteCustomer();

 

   // Создание потока

   fs = new FileStream ("c:\\Temp\\Customer.dat", FileMode.Create);

 

   // Воспользуемся поддержкой двоичного форматирования в CLR

   BinaryFormatter sf = new BinaryFormatter();

 

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

   sf.Serialize (fs, Customer1);

   sf.Serialize (fs, Customer2);

   fs.Close();

 

   // Восстановим из файла сериализованный объект

   fs = new FileStream ("c:\\Temp\\Customer.dat", FileMode.Open);

 

   Customer NewCustomer1 = (Customer)sf.Deserialize (fs);

   NewCustomer1.WriteCustomer();

 

   Customer NewCustomer2 = (Customer)sf.Deserialize (fs);

   NewCustomer2.WriteCustomer();

}

}

 

Если объект должен использоваться в другом приложении, лучшим выбором может оказаться не двоичный формат, а формат протокола SOAP (в виде XML-файла). SOAP – простой протокол доступа к объектам.

Для реализации этой задачи нужно:

• Вместо пространства имен System.Runtime.Serialization.Formatters.Binary использовать System.Runtime.Serialization.Formatters.Soap.

• Вместо класса BinaryFormatter использовать класс SoapFormatter.

• Файл создавать с расширением xml (необязательно).

 

// Сохранение объектов при помощи протокола SOAP

 

using System;

using System.IO;

using System.Runtime.Serialization;

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

using System.Runtime.Serialization.Formatters.Soap;

 

[Serializable]

class Customer

{

private int      CustomerNumber;            // N покупателя

private string CustomerName;        // Имя покупателя

private string CustomerCountry;                // Страна

 

public Customer (int Number, string Name, string Country)

{

   this.CustomerNumber = Number;

   this.CustomerName = Name;

   this.CustomerCountry = Country;

}

 

public void WriteCustomer()

{

   Console.WriteLine("Customer Number: " + CustomerNumber);

   Console.WriteLine("Customer Name: " + CustomerName);

   Console.WriteLine("Customer Country: " + CustomerCountry);

}

}

 

class SaveObj

{

public static void Main()

{

   FileStream fs;

 

   Customer Customer1 = new Customer(1, "Aлен Дилон", "Франция");

   Customer Customer2 = new Customer(2, "Иванов", "Россия");

 

   Customer1.WriteCustomer();

   Customer2.WriteCustomer();

 

   // Создание потока

   // fs = new FileStream ("c:\\Temp\\Customer.dat", FileMode.Create);

   fs = new FileStream ("c:\\Temp\\Customer.xml", FileMode.Create);

 

   // Воспользуемся поддержкой SOAP форматирования

   // BinaryFormatter sf = new BinaryFormatter();

   SoapFormatter sf = new SoapFormatter();

 

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

  sf.Serialize (fs, Customer1);

   sf.Serialize (fs, Customer2);

   fs.Close();

 

   // Восстановим из файла сериализованный объект

   fs = new FileStream ("c:\\Temp\\Customer.xml", FileMode.Open);

 

   Customer NewCustomer1 = (Customer)sf.Deserialize (fs);

   NewCustomer1.WriteCustomer();

 

   Customer NewCustomer2 = (Customer)sf.Deserialize (fs);

   NewCustomer2.WriteCustomer();

}

}

 

Классы SoapFormatter и BinaryFormatter предоставляют возможности для сериализации не только отдельных объектов, но и более сложных структур, например хеш-таблиц.

Такие структуры должны реализовывать интерфейс ISerializable. Реализация интерфейса ISerializable необходима классу в том случае, если он хочет управлять обработкой своей сериализации. Все коллекции FCL реализуют указанный интерфейс.

 

Пример сериализации хеш-таблицы.

using System;

using System.IO;

using System.Collections;

using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary;

 

public class App

{

[STAThread]

static void Main()

{

   Serialize();

   Deserialize();

}

 

static void Serialize()

{

FileStream fs;

 

   // Создать хеш-таблицу с ключем и полем данных.

   Hashtable addresses = new Hashtable();

 

   addresses.Add ("Сергей", "Москва, ул Пирогова, д.17, кв.25");

   addresses.Add ("Юлия", "Новгород, ул.Космонавтов, д. 24");

   addresses.Add ("Николай", "Тула, пр-т Ленина, д.134, кв. 76");

 

   fs = new FileStream ("C:\\Temp\\DataFile.dat", FileMode.Create);

 

   BinaryFormatter bf = new BinaryFormatter();

   try

   {

       bf.Serialize (fs, addresses);

   }

   catch (SerializationException e) // в пространстве System.Runtime.Serialization

   {

       Console.WriteLine ("Ошибка сериализации: " + e.Message);

       throw;

   }

   finally

   {

       fs.Close();

   }

}

 

static void Deserialize()

{

FileStream fs;

   Hashtable addresses = null;

 

   // Open the file containing the data that you want to deserialize.

   fs = new FileStream ("C:\\Temp\\DataFile.dat", FileMode. Open);

 

   try

   {

       BinaryFormatter bf = new BinaryFormatter();

 

       addresses = (Hashtable)bf.Deserialize(fs);

   }

   catch (SerializationException e)

   {

       Console.WriteLine("Ошибка десериализации: " + e.Message);

       throw;

   }

   finally

   {

       fs.Close();

   }

 

   foreach (DictionaryEntry de in addresses)

   {

       Console.WriteLine("{0} живет в городе {1}.", de.Key, de.Value);

   }

}

}

 

Другой способ сохранения объектов (без сериализации).

С помощью открытых методов Get…() получать значения полей объекта, записывать их в файл. При восстановлении объекта считывать поля из файла и подавать их значения в конструктор. Для полей объекта, которые не инициализируются конструктором, использовать методы Set…().

 

Дата: 2019-02-02, просмотров: 271.