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

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

Действия при десериализация, в основном, обратны действиям, соответствующим сериализации. Следующий пример открывает поток в виде файла Me.dat, создает объект типа BinaryFormatter для считывания объекта и вызывает метод Deserialize(), позволяющий восстаовить состояние этого объекта. После этого считанные данные приводятся к типу Person, и на консоль выводятся возраст и вес:

public static void DeSerialize()

{

// На этот раз сначала открывается файл

FileStream s = File.Open ("Me.dat" , FileMode.Open, FileAccess.Read);

// BinaryFormatted используется для чтения объекта (объектов) из потока

BinaryFormatter bf = new BinaryFormatter() ;

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

object о = bf.Deserialize(s) ;

//Убеждаемся в том, что объект нужного нам типа

Person р = о as Person;

if(р!=null)

Console.WriteLine("DeSerialized Person aged: {0} weight: {1}",

p.Age,p.WeightInPounds);

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

s.Close();

}

В самом начале создается экземпляр класса BinaryFormatter, который используется для десериализации данных из файла. Затем создается объект потока типа FileStream, который будет представлять поток файла. Этот поток создается с параметрами FileMode.Open, чтобы открыть файл, и FileAccess.Read для того, чтобы можно было считывать данные из открытого потока.

Самое интересное в программном коде заключается в вызове метода Deserialize(s) у форматера типа BinaryFormatter. Этот метод получает только лишь один аргумент в виде потока, из которого следует считывать данные. Метод читает данные в поисках полей данных (или свойств) сохраненного объекта и возвращает его в виде результата своей работы. Причем метод сам создает объект и инициализирует его сохраненными данными. Поэтому нам и не нужно инициализировать объект типа Person. В результате мы получаем объект типа Person и нам остается только привести типы. Но как же метод узнает класс создаваемого им объекта, который он десериализировал из потока? Дело в том, что информация о классе также сохраняется в потоке.

Объекты можно сохранять не только в файлах, но и в потоке памяти MemoryStream. Например, перед выполнением каких-либо расчетов можно сохранить состояние объекта в потоке памяти и восстановить это состояние после выполнения расчетов. В такие моменты потоки в памяти предоставляют всю мощь и скорость доступа.

Обычно, с помощью атрибута NonSerialized (не подлежащие сериализации) помечаются данные, которые получаются в результате вычислений, поскольку они могут быть вычислены по мере возникновения такой необходимости. В качестве примера можно привести класс, в котором вычисляются простые числа. Их вполне можно сохранять для увеличения скорости ответа при обращении к данному классу, однако сериализация и десериализация списка простых чисел не является необходимой, поскольку они всегда могут быть вычислены в момент обращения к классу. В других случаях некоторый член может иметь отношение только к данному экземпляру документа. Например, для объекта, который представляет документ, обрабатываемый редактором, потребуется сериализовать содержимое самого документа, но не текущую позицию, поскольку при очередной загрузке документа в качестве такой позиции просто используется начало документа.