zoukankan      html  css  js  c++  java
  • 关于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给远程客户端调用。

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

  • 相关阅读:
    【郑轻邀请赛 G】密室逃脱
    【郑轻邀请赛 C】DOBRI
    【郑轻邀请赛 F】 Tmk吃汤饭
    【郑轻邀请赛 I】这里是天堂!
    【郑轻邀请赛 B】base64解密
    【郑轻邀请赛 A】tmk射气球
    【郑轻邀请赛 H】 维克兹的进制转换
    解决adb command not found以及sdk环境配置
    adb shell 命令详解,android, adb logcat
    Unexpected exception 'Cannot run program ... error=2, No such file or directory' ... adb'
  • 原文地址:https://www.cnblogs.com/contraII/p/2549483.html
Copyright © 2011-2022 走看看