1. 程式人生 > >資料序列化處理之經驗積累(1)-BinaryFormatter

資料序列化處理之經驗積累(1)-BinaryFormatter

以前的專案使用到了資料序列化,由此抽象出了一些輔助類來更方便的實現資料序列化處理,將一一列出共享:
二進位制序列化類,此類用於類標示為Serializable,以及實現了ISerializable介面的物件的序列化:
using System;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml;

namespace Skyline.Tools.Serialize
{
    public static class BinaryFormatSerializer
    {
        private static readonly BinaryFormatter InnerBinaryFormatter = new BinaryFormatter();
        private readonly static MemoryStreamStack MemoryStreamStacker = new MemoryStreamStack();

        public static byte[] Serialize(object obj, bool compress)
        {
            if (obj == null)
            {
                return null;
            }
            byte[] info;
            MemoryStream stream = MemoryStreamStacker.GetMemoryStream();
            try
            {
                InnerBinaryFormatter.Serialize(stream, obj);
                stream.SetLength(stream.Position);
                info = stream.ToArray();
                if (compress)
                {
                    info = CompressHelper.CompressBytes(info);
                }
            }
            finally
            {
                MemoryStreamStacker.ReleaseMemoryStream(stream);
            }
            return info;
        }


        public static object Deserialize(byte[] info, bool decompress)
        {
            if (info == null || info.Length <= 0)
            {
                return info;
            }
            object ret;
            if (decompress)
            {
                info = CompressHelper.DeCompressBytes(info);
            }
            MemoryStream stream = MemoryStreamStacker.GetMemoryStream();
            try
            {
                stream.Write(info, 0, info.Length);
                stream.Position = 0L;
                ret = InnerBinaryFormatter.Deserialize(stream);
            }
            finally
            {
                MemoryStreamStacker.ReleaseMemoryStream(stream);
            }
            return ret;
        }


        public static byte[] Serialize(object obj)
        {
            return Serialize(obj, false);
        }


        public static object Deserialize(byte[] info)
        {
            return Deserialize(info, false);
        }


        public static string SerializeToBase64String(object data, bool compress)
        {
            byte[] buffer = Serialize(data, compress);
            return Convert.ToBase64String(buffer);
        }

        public static object DeserializeFromBase64String(string baseString, bool decompress)
        {
            if (String.IsNullOrEmpty(baseString))
                return null;

            byte[] buffer = Convert.FromBase64String(baseString);
            return Deserialize(buffer, decompress);
        }

        public static string SerializeToBase64String(object data)
        {
            return SerializeToBase64String(data, false);
        }

        public static object DeserializeFromBase64String(string baseString)
        {
            return DeserializeFromBase64String(baseString, false);
        }
    }
}

輔助類:   
public class MemoryStreamStack
    {
        private Stack<MemoryStream> _streams = null;

        public MemoryStreamStack():this(100)
        {

        }

        public MemoryStreamStack(int capacity)
        {
           _streams = new Stack<MemoryStream>(capacity);
        }

        public MemoryStream GetMemoryStream()
        {
            MemoryStream stream = null;
            if (_streams.Count > 0)
            {
                lock (_streams)
                {
                    if (_streams.Count > 0)
                    {
                        stream = (MemoryStream)_streams.Pop();
                    }
                }
            }
            if (stream == null)
            {
                stream = new MemoryStream(0x800);
            }
            return stream;
        }


        public void ReleaseMemoryStream(MemoryStream stream)
        {
            if (stream == null)
            {
                return;
            }
            stream.Position = 0L;
            stream.SetLength(0L);
            lock (_streams)
            {
                _streams.Push(stream);
            }
        }

        ~MemoryStreamStack()
        {
            foreach (MemoryStream memory in _streams)
            {
                memory.Dispose();
            }
            _streams.Clear();
            _streams = null;
        }

    }

壓縮類:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.IO.Compression;

namespace Skyline.Tools.Serialize
{
    public static class CompressHelper
    {
        private readonly static MemoryStreamStack MemoryStreamStacker = new MemoryStreamStack();
        public static string CompressBytesToBase64String(byte[] buffer)
        {
            if (buffer == null || buffer.Length == 0)
            {
                return "";
            }
            byte[] compressedData = CompressBytes(buffer);
            return System.Convert.ToBase64String(compressedData, 0, compressedData.Length);
        }

        public static string ConvertBytesToBase64String(byte[] buffer)
        {
            if (buffer == null || buffer.Length == 0)
            {
                return "";
            }
            return System.Convert.ToBase64String(buffer, 0, buffer.Length);
        }

        public static byte[] ConvertBase64StringToBytes(string deCompressString)
        {
            if (string.IsNullOrEmpty(deCompressString))
            {
                return new byte[0];
            }
            byte[] buffer = System.Convert.FromBase64String(deCompressString);
            return buffer;
        }


        public static byte[] DeCompressBase64StringToBytes(string deCompressString)
        {
            if (string.IsNullOrEmpty(deCompressString))
            {
                return new byte[0];
            }
            byte[] buffer = System.Convert.FromBase64String(deCompressString);

            byte[] ret = DeCompressBytes(buffer);
            return ret;
        }


        public static byte[] CompressBytes(byte[] buffer)
        {
            if (buffer == null || buffer.Length == 0)
            {
                return buffer;
            }
            byte[] compressedData;
            MemoryStream ms = MemoryStreamStacker.GetMemoryStream();
            try
            {
                using (DeflateStream compressedzipStream = new DeflateStream(ms, CompressionMode.Compress, true))
                {
                    compressedzipStream.Write(buffer, 0, buffer.Length);
                }
                ms.SetLength(ms.Position);
                //如果得到的結果長度比原來還大,則不需要壓宿,返回原來的,並帶上一位標識資料是否已壓宿過
                if (ms.Length >= buffer.Length)
                {
                    compressedData = new byte[buffer.Length + 1];
                    buffer.CopyTo(compressedData, 0);
                    compressedData[compressedData.Length - 1] = 0;
                }
                else
                {
                    compressedData = new byte[ms.Length + 1];
                    ms.ToArray().CopyTo(compressedData, 0);
                    compressedData[compressedData.Length - 1] = 1;
                }
                //ms.Close();
            }
            finally
            {
                MemoryStreamStacker.ReleaseMemoryStream(ms);
            }
            return compressedData;
        }

        private static MemoryStream DeCompressMemoryToMemory(MemoryStream ms)
        {
            MemoryStream data = MemoryStreamStacker.GetMemoryStream();
            using (DeflateStream zipStream = new DeflateStream(ms, CompressionMode.Decompress))
            {
                byte[] writeData = new byte[8192];
                // Use the ReadAllBytesFromStream to read the stream.
                while (true)
                {
                    int size = zipStream.Read(writeData, 0, writeData.Length);
                    if (size > 0)
                    {
                        data.Write(writeData, 0, size);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            return data;
        }


        public static byte[] DeCompressBytes(byte[] buffer)
        {
            if (buffer == null || buffer.Length <= 0)
            {
                return buffer;
            }
            byte[] bytes = new byte[buffer.Length - 1];
            Array.Copy(buffer, bytes, bytes.Length);

            //如果最後一位是0,說明沒有被壓宿,那麼也不需要解壓速
            if (buffer[buffer.Length - 1] == 0)
            {
                return bytes;
            }
            using (MemoryStream ms = new MemoryStream(buffer))
            {
                MemoryStream stream = null;
                try
                {
                    stream = DeCompressMemoryToMemory(ms);
                    stream.SetLength(stream.Position);
                    bytes = stream.ToArray();
                }
                finally
                {
                    MemoryStreamStacker.ReleaseMemoryStream(stream);
                }
            }
            return bytes;
        }
    }

}