Программирование C#, Java, Net - фото

Сериализация объектов в бинарный файл (c#)


Оцените данную статью

Сегодня хочу рассказать о такой замечательной и полезной вещи в языке программирования c#, как сериализация пользовательских объектов. Сериализацией называется перевод каких-либо данных в последовательность битов. Соответственно, обратный процесс восстановления исходных данных является десериализация.
Представим ситуацию, наша программа запущена, работает отлично и производит какие-то вычисления или взаимодействует с пользователем. Рано или поздно приложение завершается, корректно или нет (вылетает исключение). При этом все данные хранились в памяти компьютера и теперь они потеряны. А нам допустим хотелось бы сохранять в какой-то момент времени информацию на жестком диске. Так вот, в данном вопросе нам и поможет сериализация языка c#, для записи и чтения определенных структур данных в файл.
Для примера, пусть наше приложение содержит инфу о студентах ВУЗа. Создадим два класса Student и FIO. Объект Student будет содержать поля course (курс) , faculty (факультет) и экземпляр класса FIO (личная информация о студенте). Чтобы не усложнять, личной информацией о студенте будет только имя(firstName) и фамилия (secondName).

  1.  
  2.    //information about student
  3. public class Student
  4. {
  5.     public Student() { }
  6.  
  7.     private int course;
  8.     private string faculty;
  9.     private FIO info;
  10. }
  11.  
  12.     //personal information
  13. public class FIO
  14. {
  15.     public FIO() { }
  16.  
  17.     private string firstName;
  18.     private string secondName;
  19. }

Студентов ВУЗа много, поэтому создадим список Student’ов :

  1. List<Student> students = new List<Student>();

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

  1. public class SerializableObject
  2. {
  3.     private List<Student> students;
  4.  
  5.     public List<Student> Students
  6.     {
  7.         get { return this.students; }
  8.         set { this.students = value; }
  9.     }
  10.  
  11.     public SerializableObject() { }
  12. }

Наш класс хранит ссылку на все объекты для сериализации. Т.е. всё, что необходимо сохранить — это список студентов. Теперь давайте напишем методы, которые будут выполнять сериализацию и десериализацию объекта SerializableObject соответственно в и из файла. Поместим их в класс MySerializer:

  1. using System.IO;
  2. using System.Runtime.Serialization;
  3. using System.Runtime.Serialization.Formatters.Binary;
  4.  
  5. public class MySerializer
  6. {
  7.     public MySerializer() { }
  8.  
  9.     public void SerializeObject(string fileName, SerializableObject objToSerialize)
  10.     {
  11.         FileStream fstream = File.Open(fileName, FileMode.Create);
  12.         BinaryFormatter binaryFormatter = new BinaryFormatter();
  13.         binaryFormatter.Serialize(fstream, objToSerialize);
  14.         fstream.Close();
  15.    }
  16.  
  17.    public SerializableObject DeserializeObject(string fileName)
  18.    {
  19.         SerializableObject objToSerialize = null;
  20.         FileStream fstream = File.Open(fileName, FileMode.Open);
  21.         BinaryFormatter binaryFormatter = new BinaryFormatter();
  22.         objToSerialize = (SerializableObject)binaryFormatter.Deserialize(fstream);
  23.         fstream.Close();
  24.         return objToSerialize;
  25.    }
  26. }    

Это еще не всё, что необходимо для корректной работы нашего примера, к сожалению. Для того, чтобы данные сериализовались (десериализовались) верно, наш класс SerializableObject должен реализовать интерфейс ISerializable, а так же Serializable атрибут. Плюс для корректной десериализации надо добавить еще один конструктор. Смотрим код:

  1. [Serializable]
  2. public class SerializableObject : ISerializable
  3. {
  4.     private List<Student> students;
  5.  
  6.     public List<Student> Students
  7.     {
  8.         get { return this.students; }
  9.         set { this.students = value; }
  10.     }
  11.  
  12.     public SerializableObject() { }
  13.  
  14.     public SerializableObject(SerializationInfo sInfo, StreamingContext contextArg)
  15.     {
  16.         this.students = (List<Student>)sInfo.GetValue(«Students», typeof(List<Student>));
  17.     }
  18.  
  19.     public void GetObjectData(SerializationInfo sInfo, StreamingContext contextArg)
  20.     {
  21.         sInfo.AddValue(«Students», this.students);
  22.     }
  23. }

Поскольку объекты Student и FIO будут тоже сериализоваться, для их классов также реализуем ISerializable, плюс добавляем атрибут Serializable. Вот что должно получиться:

  1. [Serializable]
  2. public class Student : ISerializable
  3. {
  4.     public Student() { }
  5.      
  6.     public Student(SerializationInfo sInfo, StreamingContext contextArg)
  7.     {
  8.         this.course = (int)sInfo.GetValue(«Course», typeof(int));
  9.         this.faculty = (string)sInfo.GetValue(«Faculty», typeof(string));
  10.         this.info = (FIO)sInfo.GetValue(«FIO», typeof(FIO));
  11.    }
  12.  
  13.    public void GetObjectData(SerializationInfo sInfo, StreamingContext contextArg)
  14.    {
  15.        sInfo.AddValue(«Course», this.course);
  16.        sInfo.AddValue(«Faculty», this.faculty);
  17.        sInfo.AddValue(«FIO», this.info);
  18.    }
  19.  
  20.    private int course;
  21.    private string faculty;
  22.    private FIO info;
  23. }
  24.  
  25. [Serializable]
  26. public class FIO : ISerializable
  27. {
  28.     public FIO() { }
  29.  
  30.     public FIO(SerializationInfo sInfo, StreamingContext contextArg)
  31.     {
  32.         this.firstName = (string)sInfo.GetValue(«FirstName», typeof(string));
  33.         this.secondName = (string)sInfo.GetValue(«SecondName»,typeof(string));
  34.     }
  35.  
  36.     public void GetObjectData(SerializationInfo sInfo, StreamingContext contextArg)
  37.     {
  38.         sInfo.AddValue(«FirstName», this.firstName);
  39.         sInfo.AddValue(«SecondName», this.secondName);
  40.     }
  41.  
  42.     private string firstName;
  43.     private string secondName;
  44. }

Наконец-то дождались, мы на финишной прямой. Теперь для сохранения в файл нашего списка студентов вызовем SerializeObject метод, а для извлечения из файла — DeserializeObject класса MySerializer:

  1. List<Student> students = new List<Student>();
  2.  
  3. SerializableObject obj = new SerializableObject();
  4. obj.Students = students;
  5.  
  6. MySerializer serializer = new MySerializer();
  7. serializer.SerializeObject(«output.txt», obj);
  8.  
  9. obj = serializer.DeserializeObject(«output.txt»);
  10. students = obj.Students;

Это пожалуй всё о сериализации пользовательского объекта в бинарный файл языка c#. Надеюсь статья оказалась познавательной для Вас.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *