A few days back I discussed XML Serialization in these two articles: Basic XML Serialization in C#, and XML Serialization of Collections. In this article we are going to serialize the same Employee
object we serialized in those articles, but this time we are going to use Binary serialization instead.
Binary Serialization vs. XML Serialization
You might think that binary serialization and XML serialization are the same thing, the only difference being the format of the data within the created file. Well if that is the case, you would be wrong.
Binary serialization is very different from XML serialization. XML serialization is not really an actual serialization technique – in fact one might argue that Microsoft did not name it that appropriately. XML serialization does not serialize the whole object – it only creates a stream of XML data which contains the public properties of the object while ignoring any private properties.
So how can you preserve the state of an object when you are ignoring its private properties? Well, you can’t. That’s where binary serialization comes in. With binary serialization all public and private properties are serialized, therefore retaining an exact copy of the object.
This statement can obviously be proven by opening the file of a binary serialized object with a hex editor and verifying that the private properties of the object are there, but since it is a binary file that could prove a bit problematic to read for the majority of us :).
There is a simpler way to prove this – you can monitor you class’s constructor when deserializing the file. When deserializing using XML deserialization, you will notice that the class constructor for your serialized object is called. Obviously this shows that XML serialization is not retaining a copy of the actual object, but it is re-building it by instantiating your class and then populating the public properties. With binary deserialization the serialized object’s constructor is never called, and that is because there is no need for it to be called because the whole object can be rebuilt through deserialization.
Serializing an Object
To binary serialize an object, you must add the attribute [Serializable]
to each class you wish to serialize. This attribute has to be added right above your class name as shown in the below code:
using System; namespace BinarySerialization { [Serializable] public class Employee { public enum EmployeeSex { Male, Female } // Private Members private string name; private string surname; private DateTime dob; private EmployeeSex sex; private string position; // Public Properties public string Name { get { return name; } set { name = value; } } public string Surname { get { return surname; } set { surname = value; } } public DateTime DateOfBirth { get { return dob; } set { dob = value; } } public EmployeeSex Sex { get { return sex; } set { sex = value; } } public string Position { get { return position; } set { position = value; } } // Constructor public Employee() { } } }
The code to serialize our Employee
object is very straight forward as can be seen below:
private void Serialize() { // Create an instance of the Employee class Employee employee = new Employee(); employee.Name = "John"; employee.Surname = "Smith"; employee.DateOfBirth = new DateTime(1980, 10, 08); employee.Sex = Employee.EmployeeSex.Male; employee.Position = "Software Engineer"; // Create an instance of System.IO.FileStream // to save the serialized object to disk FileStream fileStream = new FileStream("C:\\Employee\\employee.data", FileMode.Create, FileAccess.Write, FileShare.None); // Create an instance of // System.Runtime.Serialization.Formatters.Binary.BinaryFormatter BinaryFormatter binaryFormatter = new BinaryFormatter(); // Serialize the object binaryFormatter.Serialize(fileStream, employee); // Close the FileStream fileStream.Close(); }
All we are doing in this code is creating an instance of our Employee
class and populating some values, then we are creating a FileStream
object to write our serialized file, and finally we are using the BinaryFormatter
class to serialize our object.
The code for deserialization is also very simple:
private void Deserialize() { Employee employee; // Create an instance of System.IO.FileStream // to load the serialized object from disk FileStream fileStream = new FileStream("C:\\Employee\\employee.data", FileMode.Open, FileAccess.Read, FileShare.Read); // Create an instance of // System.Runtime.Serialization.Formatters.Binary.BinaryFormatter BinaryFormatter binaryFormatter = new BinaryFormatter(); // Assign the deserialized object to the new employee object employee = (Employee)binaryFormatter.Deserialize(fileStream); // Close the FileStream fileStream.Close(); }
The below screenshot is displaying the Visual Studio Locals window and you can see the employee
object after the deserialization process which confirms that the binary file was deserialized correctly.
I hope you found this article interesting and you understood the difference between binary and XML serialization. Please leave your comments below and remember to subscribe to my RSS feed if you have not already done so.
Dave