c# 快速二进制序列化

       不知看到这篇文章的人,是否也曾饱受c#常见的序列化方式之苦,在数据量较小的情况下,效率上没有什么问题,一旦数据量过大,速度上简直惨不忍睹。在数据量特别大的情况下(之前需要快速保存上百兆的数据,当然,一般可能不会有如此大),文章最后提供的二进制序列化方式会比1,2快几十倍,比3快几倍。

1.object序列化

       这是一种比较常见的类序列化方式,只要定义的类以及其包含的所有变量都是可以被序列化的,就可以用这种方式,很方便,写好两个工具方法后可以很方便的在二进制文件和类之间做转换。但是,真的慢,慢的我都想骂街。

    ///<summary> 
    /// 序列化 
    /// </summary> 
    /// <param name="data">要序列化的对象</param> 
    /// <returns>返回存放序列化后的数据缓冲区</returns> 
    public static byte[] Serialize(object data)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        MemoryStream rems = new MemoryStream();
        formatter.Serialize(rems, data);
        return rems.GetBuffer();
    }

    /// <summary> 
    /// 反序列化 
    /// </summary> 
    /// <param name="data">数据缓冲区</param> 
    /// <returns>对象</returns> 
    public static object Deserialize(byte[] data)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        MemoryStream rems = new MemoryStream(data);
        data = null;
        return formatter.Deserialize(rems);
    }

2.BitConverter.GetBytes()

         这个方法可以直接将一些基础类型转化为byte数组。

3.BinaryWirter和BinaryReader

        这两个类是c#提供的二进制序列化的读写类,速度与前两个相比有天壤之别,于是,花了点时间看了一下源码(有兴趣可以自己看看源码),恍然大悟,原来还可以这么玩,于是,将它的方法搬运出来,自己写了一个类,也方便针对不同的需求添加和获取数据,我之前由于需要存取Terrain的很多信息,所以加上了一些对一二三维数组的操作。可能是由于c#提供的读写类提供了很多安全性的判断吧,自己写完之后比原生的要快上好几倍。

4.利用位运算和不安全代码来序列化

        由于整形可以和byte直接转换,不需要指针,直接用位运算就可以了,但对于浮点型和其他类型来说,就需要做一些取地址等其他操作了。这里不详细解释*((float*)&temp)这一串东西了,看看c++的指针和取地址符,再结合c#的不安全代码就可以了。由于定义了unsafe关键字,项目设置一定要改成 允许不安全代码。

        完整的类我上传到了github,通过下面的链接可以获取https://github.com/xdedzl/XFramework,在这个工程里面搜索ProtocolByte即可。

    #region 添加获取整数

    /// <summary>
    /// 将Int32转化成字节数组加入字节流
    /// </summary>
    /// <param name="num">要转化的Int32</param>
    public void AddInt32(int num)
    {
        bufferList.Add((byte)num);
        bufferList.Add((byte)(num >> 8));
        bufferList.Add((byte)(num >> 16));
        bufferList.Add((byte)(num >> 24));
    }

    /// <summary>
    /// 将字节数组转化成Int32
    /// </summary>
    public int GetInt32()
    {
        if (buffer == null)
            return 0;
        if (buffer.Length < index + 4)
            return 0;

        return (int)(buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24);
    }

    #endregion

    #region 添加获取浮点数

    /// <summary>
    /// 将float转化成字节数组加入字节流
    /// </summary>
    /// <param name="num">要转化的float</param>
    public unsafe void AddFloat(float num)
    {
        uint temp = *(uint*)&num;
        bufferList.Add((byte)temp);
        bufferList.Add((byte)(temp >> 8));
        bufferList.Add((byte)(temp >> 16));
        bufferList.Add((byte)(temp >> 24));
    }

    /// <summary>
    /// 将字节数组转化成float
    /// </summary>
    public unsafe float GetFloat()
    {
        if (buffer == null)
            return -1;
        if (buffer.Length < index + sizeof(float))
            return -1;
        uint temp = (uint)(buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24);
        return *((float*)&temp);
    }

    #endregion

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值