由于目前有些平台仍是在.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时,会发生错误,这个问题目前还没解决,就看看大家有没有答案啰.
参考数据 :
ADO.NET 1.x Dataset 序列化问题探讨
增进数据集序列化和远端性能
下载 : DataSetSurrogate
原文:大专栏 .Net 1.X平台的Web Service (WS) 数据流压缩方案
原文地址:https://www.cnblogs.com/chinatrump/p/11458295.html