Per Erik Strandberg /cv /kurser /blog

A long and silly way of doing custom serialization by using an IFormatter and encapsulating a BinaryFormatter.

Download example from [1]

We include Serialization and some other name spaces:

using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.ComponentModel;
using System.IO;

We implement a very simple class to serialize with just 3 bytes (a little too easy almost):

    class RgbValue
    {
        byte m_Red;
        byte m_Green;
        byte m_Blue;

        public byte Red { get { return m_Red; } }
        public byte Green { get { return m_Green; } }
        public byte Blue { get { return m_Blue; } }

        public RgbValue(byte red, byte green, byte blue)
        {
            m_Red = red;
            m_Green = green;
            m_Blue = blue;
        }

        public RgbValue() : this(0, 0, 0) {}

        public override string ToString()
        {
            return string.Format("({0}, {1}, {2})", m_Red, m_Green, m_Blue);
        }

    }

To format our serialization we implement our own IFormatter. This one contains a BinaryFormatter that does everything except Serialize and Deserialize.

    public class RgbFormatter : IFormatter
    {
        public object Deserialize(System.IO.Stream serializationStream)
        {
            if (serializationStream.Length < 3)
            {
                throw new SerializationException("Too short input.");
            }

            try
            {
                byte[] barr = new byte[3];
                barr[0] = (byte) serializationStream.ReadByte();
                barr[1] = (byte) serializationStream.ReadByte();
                barr[2] = (byte) serializationStream.ReadByte();

                RgbValue rgb = new RgbValue(barr[0], barr[1], barr[2]);

                return rgb;
            }
            catch (Exception ex)
            {
                throw new SerializationException("Bad input: " + ex.Message);
            }
        }

        public void Serialize(System.IO.Stream serializationStream, object graph)
        {
            if (graph is RgbValue)
            {
                RgbValue rgb = graph as RgbValue;

                serializationStream.WriteByte(rgb.Red);
                serializationStream.WriteByte(rgb.Green);
                serializationStream.WriteByte(rgb.Blue);
            }
            else
            {
                throw new SerializationException("Bad object.");
            }
        }

        #region ctors
        public RgbFormatter()
        {
            m_bf = new BinaryFormatter();
        }

        public RgbFormatter(ISurrogateSelector selector, StreamingContext context)
        {
            m_bf = new BinaryFormatter(selector, context);
        }
        #endregion

        #region encapsulation
        BinaryFormatter m_bf;

        public SerializationBinder Binder
        {
            get { return m_bf.Binder; }
            set { m_bf.Binder = value; }
        }

        public StreamingContext Context
        {
            get { return m_bf.Context; }
            set { m_bf.Context = value; }
        }


        public ISurrogateSelector SurrogateSelector
        {
            get { return m_bf.SurrogateSelector; }
            set { m_bf.SurrogateSelector = value; }
        }
        #endregion
    }

Out little test program creates a few rgb-values, serializes them to file, closes the file and reads them again.

    class Program
    {
        static void Main(string[] args)
        {
            RgbValue gray = new RgbValue(0xDD, 0xDD, 0xDD);
            RgbValue red = new RgbValue(0xDD, 0x11, 0x11);
            RgbValue blue = new RgbValue(0x00, 0x00, 0x66);

            string path = System.IO.Path.GetTempPath() + "rgbdata.dat";
            Console.WriteLine(path);
            StreamWriter sw = new StreamWriter(path);

            RgbFormatter rf1 = new RgbFormatter();
            rf1.Serialize(sw.BaseStream, gray);
            rf1.Serialize(sw.BaseStream, gray); // note: again
            rf1.Serialize(sw.BaseStream, red);
            rf1.Serialize(sw.BaseStream, blue);
            sw.Flush();
            sw.Close();

            int n = 4;
            RgbValue[] stored = new RgbValue[n];
            RgbFormatter rf2 = new RgbFormatter();
            StreamReader sr = new StreamReader(path);

            for (int i = 0; i < n; i++)
            {
                stored[i] = (RgbValue)rf2.Deserialize(sr.BaseStream);
            }

            foreach (RgbValue rgb in stored)
            {
                Console.WriteLine(rgb);
            }
        }
    }
}

This is the output I got:

C:\Documents and Settings\per\Lokala inställningar\Temp\rgbdata.dat
(221, 221, 221)
(221, 221, 221)
(221, 17, 17)
(0, 0, 102)


Tillhör Kategori Programmering