我們知道,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;
}
}