關於webservice大數據量傳輸時的壓縮和解壓縮


當訪問WebSerivice時,如果數據量很大,傳輸數據時就會很慢。為了提高速度,我們就會想到對數據進行壓縮。首先我們來分析一下。

        當在webserice中傳輸數據時,一般都采用Dataset進行數據傳輸。執行的過程就是先把Dataset轉化為xml進行傳輸,Dataset轉化為xml的格式如下:

[html]  view plain copy
 
  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 plain copy
 
  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.     }  


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM