Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лр4_сериализация.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
306.18 Кб
Скачать

16

Тверской государственный технический университет

Кафедра ЭВМ

Программирование на языке C# в среде Microsoft Visual Studio.

Сериализация.

Методические указания к лабораторным работам

по курсу "Объектно-ориентированное программирование"

Лабораторная работа № 4

Тверь 2012

Цель лабораторной работы заключается в изучении основных принципов сохранения состояния объектов путем их сериализации и приобретении практических навыков по их реализации и применению при разработке программных приложений в интегрированной среде Visual Studio.

Основными задачами, решаемыми в процессе выполнения лабораторной работы, являются:

  • Изучение особенностей основных принципов и механизмов, используемых для сериализации и десериализации программных объектов.

  • Изучение особенностей сохранения и восстановления состояния программных объектов различной сложности путем их сериализации и десериализации.

Методическое указание обсуждено на заседании кафедры ЭВМ (протокол №___от 2002_ года) и рекомендовано к печати.

Составитель: Веселов А.А.

Содержание

Стр.

1

Теоретическая часть.

3

1.1

Сериализация

3

1.2

Десериализация

4

1.3

Сериализация коллекций объектов

5

1.3.1

Описание объекта

5

1.3.2

Роль объектных графов

8

1.3.3

Настройка объектов для сериализации

9

1.3.4

Главная форма приложения

9

1.3.5

Настройка фильтра диалогового окна для открытия файлов

2

Указания к выполнению лабораторной работы

2.1

Задание на лабораторную работу

2.2

Содержание отчета по лабораторной работе

Литература

1. Теоретическая часть.

1.1. Сериализация.

Под сериализацией понимают процесс сохранения состояния объекта в дисковом файле, памяти или в каком-либо другом месте. В процессе сериализации все данные экземпляра сохраняются на некотором носителе, а в процессе десериализации объект снова наполняется таким образом, что его становится невозможно отличить от первоначального экземпляра.

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

Все, кто был вынужден постоянно думать о том, каким образом сохранить или читать данные некоего экземпляра, поймут, от какого объема вводимой информации может избавить этот атрибут. Предположим, что у вас имеется некоторый объект, который необходимо сохранить в файле и который описывается следующим образом:

public class Person

{

public Person() {}

public int Age;

public int WeightPound;

}

В С# есть возможность сериализовать члены данного экземпляра без написания какого-либо кода. Все, что вас требуется,— это включить в класс атрибут [Serializable], а все остальное сделает за вас система выполнения программ .NET.

Когда в названную систему поступает запрос на сериализацию какого-нибудь объекта, то она проверяет, реализован ли в классе данного объекта интерфейс ISerializable, И если нет, то имеется ли в этом классе атрибут Serializable.

Если в классе обнаруживается атрибут Serializable, то .NET использует отражение для того, чтобы получить все данные конкретного экземпляра — независимо от того, описаны ли они как общие, защищенные или частные, и сохранить их как представление этого объекта. Десериализация представляет собой процесс, обратный описанному, — данные считываются с носителя информации и присваиваются переменным экземплярам данного класса.

Ниже приводится пример класса, помеченного атрибутом Serializable:

[Serializable]

public class Person

{

public Person() {}

public int Age;

public int WeightInPound;

}

Для того, чтобы сохранить экземпляр класса Person, используется объект Formatter, который преобразовывает данные, хранящиеся в классе, в последовательность байтов. Система поставляется с двумя типами таких объектов, используемых по умолчании: BinaryFormatter и SoapFormatter. Программа, приведенная ниже, демонстрирует, каким образом можно использовать BinaryFormatter для сохранения объекта класса Person.

public static void Serialize()

{

// Создание объекта класса Person

Person me = Person();

// Ввод данных, подлежащих серализации

me.Age = 24;

me.WeightPound = 200;

// Использование BinaryFormatter для записи этого объекта в поток

BinaryFormatter bf = new BinaryFormatter();

// Создание на диске файла, предназначенного для хранения данного объекта

FileStream s = File.Open("me.dat", FileMode.Create, FileEccess.Write);

// Сериализация объекта

bf.Serialize(s, me);

// Закрытие потока

s.Close();

}

В этой программе вначале создается объект класса Person и задаются значения переменным Age и WeightPound, характеризующим его конкретное состояние.

После этого создается экземпляр класса BinaryFormatter. Этот класс предназначен для сериализации и десериализации объектов или даже целой совокупности связанных объектов (объектный граф) в потоке в бинарном формате. Но, прежде чем сохранить непосредственно данные, необходимо создать поток. В данном примере поток является экземпляром класса FileStream, который создает новый файл и открывает его для чтения.

Теперь есть все необходимое для сериализации. Для этого у объекта форматера типа BinaryFormatter вызывается метод Serialize(s, me). Этому методу передаются два аргумента: поток, в котором будет происходить сохранение, и объект, который необходимо сохранить в данном потоке. Для простых объектов этого вполне достаточно, а дальше объект сериализации (форматер) сделает все необходимое по сохранению значений всей совокупности переменных у объекта типа Person в указанный поток в бинарном формате. Когда сохранение будет закончено, то поток закрывается. Таким образом, четыре строчки программного кода позволили сохранить состояния объекта. Причем три из них относились к инициализации потока и форматировщика и закрытию потока.

В некоторых случаях может потребоваться указать одно или несколько полей, не подлежащих сериализации. Этого можно добиться следующим образом:

[Serializable]

public class Person

{

public Person() {}

public int Age;

[NonSerialized]

public int WeightInPound;

}

В процессе сериализации такого класса будет сохраняться только член класса Age, а член WeightInPound сохраняться не будет и, следовательно, не будет извлекаться при лесериализации.