.Net 1.X平台的Web Service (WS) 資料流壓縮方案
由於目前有些平台仍是在.Net 1.X上面,雖然GZipStream可以壓縮資料流,但它必需在.Net 2.0以上的平台才能用,但也不代表.Net 1.X就只能乖乖的認命,接受這個結果,其實在.Net 1.X上,也有一個方法可以做到資料流的壓縮,微軟有提供一個物件DataSetSurrogate來協助開發人員不用花太多的時間在Coding上,就可以達成目標.
仔細去看DataSetSurrogate的原始碼後,大至上就可以了解到它是怎麼去"簡化"資料量,怎麼運用多個Array List及HashTable去儲存DataSet裡的資料,雖然壓縮率沒有GZipStream來的高,但也算很優了,而運用也相當的簡單,不用寫太多的程式碼在上面,以下就是程式碼部份的簡介 :
首先,要去下載DataSetSurrogate的這個檔案,下載解壓後,可以看到VB及CSharp的目錄,這兩個目錄都一樣,只是一個是用VB寫的,另一個是C#,而這目錄以下,有三個目錄 : DataSetSurrogate,DSServer,TestSurrogate.而TestSurrogate為測試的專案,DSServer是測試專案的DataAcess的部份,除了要測試,不然可以不用管它,因為我們要用的是DataSetSurrogate,剛解壓是沒有編譯過的,所以要先Complier這個專案,才能得到我們要用的DLL物件.
當我們得到DataSetSurrogate這個物件後,就可以拿到我們的專案裡用,當然,不論是Client還是Server,都要記得先將DataSetSurrogate加入參考才能用,以下就是程式範例 :
Server Side :
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
[WebMethod]
public byte[] GetDSBinary()
{
try
{
DataSetSurrogate dss=new DataSetSurrogate(LoadData().Copy());
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms=new MemoryStream();
bf.Serialize(ms,dss);
return ms.GetBuffer();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
private DataSet LoadData()
{
try
{
DataSet ds=new DataSet();
//從資料庫取得資料
return ds;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
Server端的Web Service就只有這樣,就可以了,所以程式碼部份,真的很少. 而Client端的部份,也是一樣,並不多.
Client Side :
using System.Runtime.Serialization.Formatters.Binary;
//using 剛剛做好的WebService
private void button1_Click(object sender, System.EventArgs e)
{
WS.Service1 w=new WSGet.WS.Service1();//new 剛剛的WebService
try
{
dataGrid1.DataSource=null;
this.Cursor=Cursors.WaitCursor;
byte[] bt=w.GetDSBinary();
MemoryStream ms=new MemoryStream(bt);
BinaryFormatter bf=new BinaryFormatter();
object obj=bf.Deserialize(ms);
DataSetSurrogate dss=(DataSetSurrogate)obj;
dataGrid1.DataSource=dss.ConvertToDataSet().Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
this.Cursor=Cursors.Default;
}
}
Client端這樣也就OK了,測試了一下壓縮量的差異,結果如下表 :
壓縮前 | 壓縮後 | 壓縮比 | |
GZipStream | 18,368,067 bytes | 4,445,278 bytes | 75% |
DataSetSurrogate | 6,563,150 bytes | 2,872,540 bytes | 45% |
雖然有20%的差異,但也是不錯了,不知道GZipStream+Serialize+DataSetSurrogate會是什麼樣的結果~(預計效果可能不大,依據微軟的說法,.Net 2.0的BinaryFormatter已將DataSet的內容以精簡化之二進位制格式化,所以不需再用DataSetSurrogate)
之所以會去翻出.Net 1.X的舊平台解決方案,主要也是因為現在公司的Client端部份仍是.Net1.X,無法在2.0上運作,雖然Server端是2.0的,也是無法使用GZipStream,但說到這裡,有一個重點出現了,我嘗試過用DataSetSurrogate放在.Net2.0的執行,從2.0的Server端丟回到1.X的Client端,結果會跳出錯誤訊息"可能原因為版本不相符。型別 System.Globalization.CompareInfo 有 2 個成員,但還原序列化後的成員數目卻為 3。".把Server設為1.X就OK了,初步判斷,應該是BinaryFormatter的問題,因為.Net1.X與2.0的不同,如上所述"Net 2.0的BinaryFormatter已將DataSet的內容以精簡化之二進位制格式化",而1.X的並沒有,所以可能因此,在這部份上,造成我在Deserialize時,會發生錯誤,這個問題目前還沒解決,就看看大家有沒有答案囉.
參考資料 :
下載 : DataSetSurrogate