Simple Data Serialization

The Windows .NET 2.0 framework provides different methods for serializing objects, but sometimes all that you need is simple binary data serialization. Here is one approach that is a bit more homespun than what the framework provides, but there is no doubt how it serializes data without requiring much code at all.

The key to this method is the BitConverter class. This class contains methods for converting standard data types to byte arrays and byte arrays back into standard data types. The BitConverter.GetBytes method takes a standard data type like a bool, int, double, long, etc. and converters the value into a byte array representation of how it is stored in memory. Methods such as ToBoolean, ToInt32, and ToDouble take the byte array representation and assign it to a standard data type.

Here is an example of an application (PixFlip Animator) that saves out and opens an animation project where the width and height of the movie along with all of the image frames are stored:

Save Method

using (Stream file = File.OpenWrite(fileName))
{
   byte[] intBuffer = BitConverter.GetBytes(_imageWidth);
   file.Write(intBuffer, 0, intBuffer.Length);
   intBuffer = BitConverter.GetBytes(_imageHeight);
   file.Write(intBuffer, 0, intBuffer.Length);

   foreach (MemoryStream stream in _imageStreams)
   {
      intBuffer = BitConverter.GetBytes((int)stream.Length);
      file.Write(intBuffer, 0, intBuffer.Length);
      byte[] streamBuffer = stream.ToArray();
      file.Write(streamBuffer, 0, streamBuffer.Length);
   }
}

Open Method

FrameManager retval = null;

using (Stream file = File.OpenRead(fileName))
{
   int width, height;
   byte[] intBuffer = new byte[sizeof(int)];
   file.Read(intBuffer, 0, intBuffer.Length);
   width = BitConverter.ToInt32(intBuffer, 0);
   file.Read(intBuffer, 0, intBuffer.Length);
   height = BitConverter.ToInt32(intBuffer, 0);

   retval = new FrameManager(width, height);

   int i = 0;
   while (file.Read(intBuffer, 0, intBuffer.Length) > 0)
   {
      int frameImageSize = BitConverter.ToInt32(intBuffer, 0);
      byte[] streamBuffer = new byte[frameImageSize];
      if (file.Read(streamBuffer, 0, frameImageSize) != frameImageSize)
         throw new Exception("Invalid project file.");

      retval.Insert(i++, new MemoryStream(streamBuffer));
   }
}

This example just stores out a few properties, data lengths, and the data streams to a file. This approach tends to work well when much of the data is binary to begin with.