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


Сохранение объектов представляет собой определенную проблему. Связано это с тем, что обычно переменные объекта являются недоступными в программе. Для решения этой проблемы создано пространство имен 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-08; просмотров: 563;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

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

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.023 сек.