zoukankan      html  css  js  c++  java
  • 关于webservice大数据量传输时的压缩和解压缩

          当访问WebSerivice时,如果数据量很大,传输数据时就会很慢。为了提高速度,我们就会想到对数据进行压缩。首先我们来分析一下。

          当在webserice中传输数据时,一般都采用Dataset进行数据传输。执行的过程就是先把Dataset转化为xml进行传输,Dataset转化为xml的格式如下:

    <DataSetName>
      <DataTableName>
        <Column1Name>.......</Column1Name>
        <Column2Name>.......</Column2Name>
        <Column3Name>.......</Column3Name>
      </DataTableName>
    ...
    ...
    ...
    <DataSetName>

    很明显的可以看到,Datase在t转化为xml的过程中增加了大量的xml格式数据,这样也就加大了传输量。


    经过分析,我们就可以找到两个解决数据传输量大的问题的方法:

    1.不直接使用Dataset来传输数据,避免转化为xml时增加的额外数据。所以我们可以将Dataset转化为DataSetSurrogate对象用Binary进行序列化,用二进制数据来传输数据。当然你也可以采用其他更好的方式,总之就是减少为了传输而增加的额外数据

    2.对数据进行压缩后再传输,至于压缩的方法有很多。 

    参考代码如下(这里使用的是.net自带的Gzip进行压缩的,压缩效率可能不是太好):

    //=========================================================================
        //类名:DataSetZip
        /// <summary>
        /// 当DataSet中的数据量很大时,进行网络数据传递时,速度会很慢。
        /// 本类将Dataset转化为DataSetSurrogate对象用Binary进行序列化,
        /// 然后进行压缩之后进行传输,最后进行解压缩
        /// </summary>
        /// <remarks>
        /// 将DataSet中的DataTable中的数据进行转换或复原
        /// </remarks>
        /*=========================================================================
         变更记录
         序号       更新日期        开发者      变更内容
         001        2008/7/22       张          新建
         =========================================================================*/
        public class DataSetZip
        {
            //消息ID
            private const string MSG_ERR_INTERNAL = "MFWE00016";
    
            /// <summary>
            /// 取得将DataSet转化为DataSetSurrogate对象用Binary进行序列化,并压缩后的二进制数组
            /// </summary>
            /// <param name="dsData">需压缩的DataSet数据</param>
            /// <returns>压缩后二进制数组</returns>
            public static byte[] GetDataSetZipBytes(DataSet dsData)
            {
                try{
                DataSetSurrogate dss = new DataSetSurrogate(dsData);
                BinaryFormatter ser = new BinaryFormatter();
                MemoryStream ms = new MemoryStream();
                ser.Serialize(ms, dss);
                byte[] buffer = ms.ToArray();
                byte[] Zipbuffer = Compress(buffer);
                return Zipbuffer;
                }
                catch (Exception ex)
                {
                    throw new DataSetConverterException(MSG_ERR_INTERNAL, new string[] { "DataSetZip", "GetDataSetZipBytes" }, ex, null);
                }
            }
    
            /// <summary>
            /// 用.net自带的Gzip对二进制数组进行压缩,压缩比率可能不是太好
            /// </summary>
            /// <param name="data">二进制数组</param>
            /// <returns>压缩后二进制数组</returns>
            public static byte[] Compress(byte[] data)
            {
                MemoryStream ms = new MemoryStream();
                Stream zipStream = null;
                zipStream = new GZipStream(ms, CompressionMode.Compress, true);
                zipStream.Write(data, 0, data.Length);
                zipStream.Close();
                ms.Position = 0;
                byte[] compressed_data = new byte[ms.Length];
                ms.Read(compressed_data, 0, int.Parse(ms.Length.ToString()));
                return compressed_data;
            }
    
            /// <summary>
            /// 对二进制数组进行解压缩
            /// </summary>
            /// <param name="data">二进制数组</param>
            /// <returns>解压缩后的DataSet</returns>
            public static DataSet Decompress(byte[] data)
            {
                try
                {
                    byte[] buffer = null;
                    MemoryStream zipMs = new MemoryStream(data);
                    buffer = EtractBytesFormStream(zipMs, data.Length);
                    BinaryFormatter ser = new BinaryFormatter();
                    DataSetSurrogate dss = ser.Deserialize(new MemoryStream(buffer)) as DataSetSurrogate;
                    DataSet dsData = dss.ConvertToDataSet();
    
                    return dsData;
                }
                catch(Exception ex)
                {
                    throw new DataSetConverterException(MSG_ERR_INTERNAL, new string[] { "DataSetZip", "Decompress" }, ex, null);
                }
            }
    
            /// <summary>
            /// 用.net自带的Gzip对数据流进行解压缩
            /// </summary>
            /// <param name="zipMs">数据流</param>
            /// <param name="dataBlock">数据长度</param>
            /// <returns>解压缩后的二进制数组</returns>
            public static byte[] EtractBytesFormStream(MemoryStream zipMs, int dataBlock)
            {
                byte[] data = null;
                int totalBytesRead = 0;
                Stream zipStream = null;
                zipStream = new GZipStream(zipMs, CompressionMode.Decompress);
                while (true)
                {
                    Array.Resize(ref data, totalBytesRead + dataBlock + 1);
                    int bytesRead = zipStream.Read(data, totalBytesRead, dataBlock);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    totalBytesRead += bytesRead;
                }
                Array.Resize(ref data, totalBytesRead);
                return data;
            }
        }
  • 相关阅读:
    A 【NOIP2012 day2】疫情控制
    Leetcode(886)-可能的二分法
    判断链表是否有环
    如何判断图的连通
    图的DFS与BFS
    struct 和 class的区别
    最小生成树-kruskal算法
    Leetcode(712)-账户合并
    全局最小割
    Leetcode(29)-两数相除
  • 原文地址:https://www.cnblogs.com/rxjy/p/3282334.html
Copyright © 2011-2022 走看看