首页 > 代码库 > 关于webservice大数据量传输时的压缩和解压缩

关于webservice大数据量传输时的压缩和解压缩

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

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

[html] view plaincopy
 
  1. <DataSetName>  
  2.   <DataTableName>  
  3.     <Column1Name>.......</Column1Name>  
  4.     <Column2Name>.......</Column2Name>  
  5.     <Column3Name>.......</Column3Name>  
  6.   </DataTableName>  
  7. ...  
  8. ...  
  9. ...  
  10. <DataSetName>  

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


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

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

2.对数据进行压缩后再传输,至于压缩的方法有很多,可以参考我的文章.net中压缩和解压缩的研究

 

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

[html] view plaincopy
 
  1. //=========================================================================  
  2.     //类名:DataSetZip  
  3.     /// <summary>  
  4.     /// 当DataSet中的数据量很大时,进行网络数据传递时,速度会很慢。  
  5.     /// 本类将Dataset转化为DataSetSurrogate对象用Binary进行序列化,  
  6.     /// 然后进行压缩之后进行传输,最后进行解压缩  
  7.     /// </summary>  
  8.     /// <remarks>  
  9.     /// 将DataSet中的DataTable中的数据进行转换或复原  
  10.     /// </remarks>  
  11.     /*=========================================================================  
  12.      变更记录  
  13.      序号       更新日期        开发者      变更内容  
  14.      001        2008/7/22       张          新建  
  15.      =========================================================================*/  
  16.     public class DataSetZip  
  17.     {  
  18.         //消息ID  
  19.         private const string MSG_ERR_INTERNAL = "MFWE00016";  
  20.   
  21.         /// <summary>  
  22.         /// 取得将DataSet转化为DataSetSurrogate对象用Binary进行序列化,并压缩后的二进制数组  
  23.         /// </summary>  
  24.         /// <param name="dsData">需压缩的DataSet数据</param>  
  25.         /// <returns>压缩后二进制数组</returns>  
  26.         public static byte[] GetDataSetZipBytes(DataSet dsData)  
  27.         {  
  28.             try{  
  29.             DataSetSurrogate dss = new DataSetSurrogate(dsData);  
  30.             BinaryFormatter ser = new BinaryFormatter();  
  31.             MemoryStream ms = new MemoryStream();  
  32.             ser.Serialize(ms, dss);  
  33.             byte[] buffer = ms.ToArray();  
  34.             byte[] Zipbuffer = Compress(buffer);  
  35.             return Zipbuffer;  
  36.             }  
  37.             catch (Exception ex)  
  38.             {  
  39.                 throw new DataSetConverterException(MSG_ERR_INTERNAL, new string[] { "DataSetZip", "GetDataSetZipBytes" }, ex, null);  
  40.             }  
  41.         }  
  42.   
  43.         /// <summary>  
  44.         /// 用.net自带的Gzip对二进制数组进行压缩,压缩比率可能不是太好  
  45.         /// </summary>  
  46.         /// <param name="data">二进制数组</param>  
  47.         /// <returns>压缩后二进制数组</returns>  
  48.         public static byte[] Compress(byte[] data)  
  49.         {  
  50.             MemoryStream ms = new MemoryStream();  
  51.             Stream zipStream = null;  
  52.             zipStream = new GZipStream(ms, CompressionMode.Compress, true);  
  53.             zipStream.Write(data, 0, data.Length);  
  54.             zipStream.Close();  
  55.             ms.Position = 0;  
  56.             byte[] compressed_data = new byte[ms.Length];  
  57.             ms.Read(compressed_data, 0, int.Parse(ms.Length.ToString()));  
  58.             return compressed_data;  
  59.         }  
  60.   
  61.         /// <summary>  
  62.         /// 对二进制数组进行解压缩  
  63.         /// </summary>  
  64.         /// <param name="data">二进制数组</param>  
  65.         /// <returns>解压缩后的DataSet</returns>  
  66.         public static DataSet Decompress(byte[] data)  
  67.         {  
  68.             try  
  69.             {  
  70.                 byte[] buffer = null;  
  71.                 MemoryStream zipMs = new MemoryStream(data);  
  72.                 buffer = EtractBytesFormStream(zipMs, data.Length);  
  73.                 BinaryFormatter ser = new BinaryFormatter();  
  74.                 DataSetSurrogate dss = ser.Deserialize(new MemoryStream(buffer)) as DataSetSurrogate;  
  75.                 DataSet dsData = dss.ConvertToDataSet();  
  76.   
  77.                 return dsData;  
  78.             }  
  79.             catch(Exception ex)  
  80.             {  
  81.                 throw new DataSetConverterException(MSG_ERR_INTERNAL, new string[] { "DataSetZip", "Decompress" }, ex, null);  
  82.             }  
  83.         }  
  84.   
  85.         /// <summary>  
  86.         /// 用.net自带的Gzip对数据流进行解压缩  
  87.         /// </summary>  
  88.         /// <param name="zipMs">数据流</param>  
  89.         /// <param name="dataBlock">数据长度</param>  
  90.         /// <returns>解压缩后的二进制数组</returns>  
  91.         public static byte[] EtractBytesFormStream(MemoryStream zipMs, int dataBlock)  
  92.         {  
  93.             byte[] data = null;  
  94.             int totalBytesRead = 0;  
  95.             Stream zipStream = null;  
  96.             zipStream = new GZipStream(zipMs, CompressionMode.Decompress);  
  97.             while (true)  
  98.             {  
  99.                 Array.Resize(ref data, totalBytesRead + dataBlock + 1);  
  100.                 int bytesRead = zipStream.Read(data, totalBytesRead, dataBlock);  
  101.                 if (bytesRead == 0)  
  102.                 {  
  103.                     break;  
  104.                 }  
  105.                 totalBytesRead += bytesRead;  
  106.             }  
  107.             Array.Resize(ref data, totalBytesRead);  
  108.             return data;  
  109.         }  
  110.     }