我们知道,DataSet可以在Remoting或者WebServices中传递,因为它实现了ISerializable接口。但是,DataSet的序列化并非真正的binary,而是先转换成XML,然后再binary,所以它的尺寸可想而之。
对于大记录数的DataSet,如果不优化其尺寸,那么必然会影响传输效率。如何优化呢?
目前,关于这方面的文章有如下几篇:
1.http://msdn.microsoft.com/msdnmag/issues/02/12/cuttingedge/default.aspx?side=true
2.http://support.microsoft.com/kb/829740
3.http://www.eggheadcafe.com/articles/20031219.asp
4.http://www.microsoft.com/taiwan/msdn/columns/adonet/AdoNet_20041231.htm
其中,第三篇中说到其效率很高。但实际应用时,发现在不同操作系统/硬件环境的机器之间,解压缩时会发生错误。
其实,最直接的优化尺寸的办法就是压缩。下面给出了采用#ziplib,如何来封装DataSet的序列化和反序列化:
public class CompressDataSet
{
public static DataSet ReadCompressStream(Stream data)
{
if(data != null)
data.Seek(0, SeekOrigin.Begin);
int s1 = (int)data.Length;
Console.WriteLine("compressed size: " + s1);
MemoryStream m = new MemoryStream();
InflaterInputStream mem = new InflaterInputStream(data);
byte[] buffer = new byte[4096];
while(true)
{
int size = mem.Read(buffer, 0, buffer.Length);
m.Write(buffer, 0, size);
if(size == 0)
break;
}
mem.Close();
Console.WriteLine("original size: " + m.Length);
Console.WriteLine("compress ratio: {0}", (s1 * 1.0 / m.Length).ToString("0.###"));
m.Seek(0, SeekOrigin.Begin);
BinaryFormatter bf = new BinaryFormatter();
DataSet ds = bf.Deserialize(m) as DataSet;
m.Close();
return ds;
}
public static Stream WriteCompressDataSet(DataSet data)
{
MemoryStream mem = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(mem, data);
byte[] buffer = mem.ToArray();
mem.Close();
MemoryStream memC = new MemoryStream();
ICSharpCode.SharpZipLib.Zip.Compression.Deflater defl =
new ICSharpCode.SharpZipLib.Zip.Compression.Deflater(9);
DeflaterOutputStream mem1 = new DeflaterOutputStream(memC, defl);
mem1.Write(buffer, 0, buffer.Length);
mem1.Close();
MemoryStream m = new MemoryStream(memC.ToArray());
return m;
}
}