• 关于wcf序列化后的压缩示例


    序列化的方法很多,建议用ProtoBuf,百度下protobuf-net.dll下载这个组件,把它引进到我们的项目中。

    怎么使用它呢?

    第一步,在需要序列化的类里面增加ProtoBuf格式,例如:

    [ProtoContract]
        public class WcfResult
        {
    
            [ProtoMember(1,IsRequired = true)]
            public int Unid{ get; set; }
    
            [ProtoMember(2)]
            public string Msg { get; set; }
    
            [ProtoMember(3)]
            public List<int> Ids{ get; set; }
    
            [ProtoMember(4)]
            public bool IsTrue { get; set; }
    }

    IsRequired表示在这个消息中这个字段是必须的,就像数据库中的非空字段一样的,必须要有值。

    注意的是,类的名称上面要有[ProtoContract],属性也必须打上[ProtoMember()],否则序列化将不通过。

    第二步,序列化与反序列化的方法:

    public static byte[] ProtobufSerialize<T>(T obj)
    {
        using (MemoryStream memory = new MemoryStream())
        {
            Serializer.Serialize<T>(memory, obj);
            return memory.ToArray();
        }
    }
    
     public static T ProtobufDeserialize<T>(byte[] data) where T: class
    {
        using (MemoryStream memory = new MemoryStream(data))
        {
            return Serializer.Deserialize<T>(memory);
        }
    }

    很多时候,wcf传输的对象非常巨大,需要压缩。这里只是简单的提供自带的压缩方法。大家也可以去下载ICSharpCode这个东西,研究一下。

      public static string ZipCompress(byte[] buffer)
            {
                try
                {
                    string str = "";
                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (GZipStream gzipStream = new GZipStream(ms, CompressionMode.Compress, true))
                        {
                            gzipStream.Write(buffer, 0, buffer.Length);
                        }
                        ms.Flush();
                        str = Convert.ToBase64String(ms.ToArray());
                    }
                    return str;
                }
                catch (Exception exp)
                {
                    return null;
                }
            }
    
            public static byte[] UNZip(string str)
            {
                try
                {
                    MemoryStream reMs = new MemoryStream();
                    byte[] buffer = Convert.FromBase64String(str);
                    using (MemoryStream ms = new MemoryStream(buffer))
                    {
                        using (GZipStream gzipStream = new GZipStream(ms, CompressionMode.Decompress))
                        {
                            byte[] tmpBuffer = new byte[4096]; 
                            int offset = 0;
                            while ((offset = gzipStream.Read(tmpBuffer, 0, tmpBuffer.Length)) > 0)
                            {
                                reMs.Write(tmpBuffer, 0, offset);
                            }
                        }
                    }
                    reMs.Flush();
                    return reMs.ToArray();
                }
                catch (Exception exp)
                {
                    return null;
                }
            }

    最后,我们把整个例子串起来,代码如下。

    //对象(1)
    WcfResult wcf = new WcfResult({Unid=123,Msg="hello contra!"});
    //序列化(2)
    byte[] buffer = ProtobufSerialize(wcf);
    //压缩(3)
    string tmpwcf = ZipHelper.ZipCompress(buffer);
    //解压缩(4)
    byte[] tmpbuffer = ZipHelper.UNZip(tmpwcf);
    //反序列化(5)
    WcfResult ret = ProtobufDeserialize(tmpbuffer);

    (2)(3)放在wcf服务端。

    (4)(5)wcf客户端代码,提供dll给远程客户端调用。

    完成了,测试一下,对于纯数字的实体压缩率不是很高。。好吧。。有空再研究。

  • 相关阅读:
    【ABAP系列】SAP 系统的消息类型分析 MESSAGE TYPE
    【FICO系列】SAP FICO-模块 关于固定资产年结和折旧的问题
    【ABAP系列】SAP ABAP 刷新SCREEN的方法
    【ABAP系列】SAP ABAP 控制ALV单元格编辑后获取新的数值
    【ABAP系列】SAP ABAP系统变量及注释
    【EWM系列】SAP EWM凭证对象表概览
    【EWM系列】SAP EWM中仓库任务WT创建的函数
    教你快速录制gif动图
    阿里巴巴的26款超神Java开源项目!
    HTTP和HTTPS协议,看一篇就够了
  • 原文地址:https://www.cnblogs.com/contraII/p/2549483.html
Copyright © 2020-2023  润新知