• 关于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;
            }
        }
  • 相关阅读:
    UVa 10118 记忆化搜索 Free Candies
    CodeForces 568B DP Symmetric and Transitive
    UVa 11695 树的直径 Flight Planning
    UVa 10934 DP Dropping water balloons
    CodeForces 543D 树形DP Road Improvement
    CodeForces 570E DP Pig and Palindromes
    HDU 5396 区间DP 数学 Expression
    HDU 5402 模拟 构造 Travelling Salesman Problem
    HDU 5399 数学 Too Simple
    CodeForces 567F DP Mausoleum
  • 原文地址:https://www.cnblogs.com/rxjy/p/3282334.html
Copyright © 2020-2023  润新知