I recently faced the challenge of creating the functionality that allows a class to
be saved to disk. Normally I would use databases or other structured format like XML, but this time, the classes were invalid. Invalid in the sense of not having all its
properties set and therefore wasn’t fit for saving to any structured data store. Default
values to the properties of the class were not an option.
Serialization was the way to go. I knew that. XML serialization was not an option
due to the fact that XML data must be structured, and this was not the case. The only
way to go was to use binary serialization. A binary serialization is like taking a
snapshot of a class/object at its current state and save it. It does not care about
the structure of the class, it just takes a snapshot. Serialization is not a new thing, but with .NET it’s a lot easier.
Remember that it could be relatively expensive to serialize objects, so don’t use
it without knowing the impact. I’ve made a C# 2.0 helper class that uses generics
to deserialize the serialized data stream back to its original state. The example
only works in C# 2.0.
#region Using
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Xml;
using System.Globalization;
#endregion
/// <summary>
/// A serialization helper class.
/// </summary>
public static class Serializer
{
private static object _Lock = new object();
#region Serialize
/// <summary>
/// Serialize an object and store it in a file.
/// </summary>
/// <param name="mode">The instance of an object to serialize</param>
/// <param name="instance">The instance of an object to serialize.</param>
/// <param name="filePath">The location on disk.</param>
/// <returns>A serialized MemoryStream.</returns>
public static void Serialize(SerializeMode
mode, object instance, string filePath)
{
using (FileStream
fs = new FileStream(filePath, FileMode.Create))
{
MemoryStream stream = Serialize(mode, instance);
byte[] buffer = stream.ToArray();
fs.Write(buffer, 0, buffer.Length);
fs.Flush();
}
}
/// <summary>
/// Serializes any instances of any objects.
/// </summary>
/// <param name="mode">The instance of an object to serialize</param>
/// <param name="instance">The instance of an object to serialize.</param>
/// <returns>A serialized MemoryStream.</returns>
public static MemoryStream
Serialize(SerializeMode mode, object instance)
{
if (instance
== null)
throw new ArgumentNullException("The
instance object is null.");
lock (_Lock)
{
MemoryStream stream = new MemoryStream();
switch (mode)
{
case SerializeMode.Xml:
SerializeXml(ref stream, ref instance);
return stream;
default:
SerializeBinary(ref stream, ref instance);
return stream;
}
}
}
private static void SerializeBinary(ref MemoryStream
stream, ref object instance)
{
BinaryFormatter bfor = new BinaryFormatter();
bfor.Serialize(stream, instance);
bfor = null;
}
private static void SerializeXml(ref MemoryStream
stream, ref object instance)
{
XmlSerializer ser = new XmlSerializer(instance.GetType());
XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
xsn.Add(string.Empty, null);
ser.Serialize(stream, instance, xsn);
ser = null;
}
#endregion
#region Deserialize
/// <summary>
/// Deserialize an object from a byte array
/// </summary>
/// <param name="mode">The mode to deserialize the object.</param>
/// <param name="instance">Specify an instance of an object to deserialize.</param>
/// <param name="buffer">A byte array containing the serialized object, that needs
/// to be deserialized</param>
/// <returns>A deserialized object.</returns>
public static T
Deserialize<T>(SerializeMode mode, T instance, byte[] buffer)
{
if (buffer
== null)
throw new ArgumentNullException("The byte
array is null.");
lock (_Lock)
{
switch (mode)
{
case SerializeMode.Xml:
return DeserializeXml<T>(instance, buffer);
default:
return DeserializeBinary<T>(instance, buffer);
}
}
}
/// <summary>
/// Deserialize an object from a location on disk or network.
/// </summary>
/// <param name="mode">The mode to deserialize the object.</param>
/// <param name="instance">Specify an instance of an object to deserialize.</param>
/// <param name="filePath">The path to the serialized object.</param>
/// <returns>A deserialized object.</returns>
public static T
Deserialize<T>(SerializeMode mode, T instance, string filePath)
{
byte[] buffer = null;
try
{
using (FileStream
fs = new FileStream(filePath, FileMode.Open))
{
buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
return Deserialize<T>(mode, instance, buffer);
}
}
finally
{
buffer = null;
}
}
/// <summary>
/// Deserializes an object from a byte array
/// </summary>
private static T
DeserializeXml<T>(T instance, byte[] buffer)
{
using (MemoryStream
stream = new MemoryStream(buffer))
{
XmlSerializer ser = new XmlSerializer(typeof(T));
instance = (T)ser.Deserialize(stream);
return instance;
}
}
/// <summary>
/// Deserializes the object from a byte array.
/// </summary>
/// <param name="instance">Specify an instance of an object to deserialize.</param>
/// <param name="array">A serialized byte array</param>
private static T
DeserializeBinary<T>(T instance, byte[] array)
{
BinaryFormatter bf;
MemoryStream ms = null;
try
{
ms = new MemoryStream(array);
{
bf = new BinaryFormatter();
instance = (T)bf.Deserialize(ms);
return instance;
}
}
finally
{
bf = null;
if (ms
!= null)
ms.Close();
ms = null;
}
}
#endregion
}
#region Enumeration
/// <summary>
/// The type of serialization.
/// </summary>
public enum SerializeMode
{
/// <summary>Will serialize to a binary format.</summary>
Binary,
/// <summary>Will serialize to an XML format.</summary>
Xml
}
#endregion
* $4.95/month BlogEngine.net Hosting – Click Here!