Основы сериализации объектов

Основы сериализации объектов

Термин сериализация означает процесс переноса состояния объекта в поток, Соответствующая сохраненная последовательность данных содержит всю информацию, необходимую для реконструкции объекта, если в дальнейшем возникает необходимость в его использовании. С помощью такой технологии очень просто сохранять огромные объемы данных (в самых разных форматах). Во многих случаях сохранение данных приложения с помощью сервиса сериализации оказывается намного менее неуклюжим, чем прямое использование средств чтения/записи, предлагаемых в рамках пространства имен System.IO.

Предположим, например, что вы создали приложение с графическим интерфейсом и хотите обеспечить конечным пользователям возможность сохранить информацию об их предпочтениях. Для этого вы можете определить класс (например, с именем UserPrefs), инкапсулирующий, скажем, 20 полей данных. Если использовать тип System.IO.BinaryWriter, вам придется вручную сохранять каждое поле объекта UserPrefs. А когда вы захотите загрузить данные из соответствующего файла обратно в память, вам придется использовать System.IO.BinaryReader и (снова вручную) прочитать каждое значение, чтобы сконфигурировать новый объект UserPrefs.

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

static void Main(string[] args) {

 // Предполагаем, что для UserPrefs

 // указано [Serializable].

 UserPrefs userData = new UserPrefs();

 userData.WindowColor = "Yellow";

 userData.FontSize = "50";

 userData.IsPowerUser = false;

 // Теперь сохраним объект в файле user.dat.

 BinaryFormatter binFormat = new BinaryFormatter();

 Stream fStream = new FileStream("user.dat", FileMode.Create, FileAccess.Write, FileShare.None);

 binFormat.Serialize(fStream, userData); fStream.Close();

 Console.ReadLine();

}

Сохранять объекты с помощью средств сериализации .NET очень просто, но процессы, происходящие при этом в фоновом режиме, оказываются весьма сложными. Например, когда объект сохраняется в потоке, все соответствующие данные (базовые классы, вложенные объекты и т.п.) автоматически сохраняются тоже. Таким образом, при попытке выполнить сериализацию производного класса в этом процессе будет задействована вся цепочка наследования.

Как вы сможете убедиться позже, множество взаимосвязанных объектов можно представить в виде объектного графа. Сервис сериализации .NET позволяет сохранить и объектный граф, причем в самых разных форматах. В предыдущем примере программного кода использовался тип BinaryFormatter, поэтому состояние объекта UserPrefs сохранялось в компактном двоичном формате. Если использовать другие типы, то объектный граф можно сохранить в формате SOAP (Simple Object Access Protocol – простой протокол доступа к объектам) или в формате XML. Эти форматы могут быть полезны тогда, когда необходимо гарантировать, что ваши сохраненные объекты легко перенесут "путешествие" через операционные системы, языки и архитектуры.

Наконец, следует понимать, что объектный граф можно сохранить в любом производном от System.IO.Stream типе. В предыдущем примере объект UserPrefs сохранялся в локальном файле с помощью типа FileStream. Но если бы требовалось сохранить объект в памяти, следовало бы использовать тип MemoryStream. Это необходимо для того, чтобы последовательность данных корректно представляла состояния объектов соответствующего графа.