问题描述
|
我在使用GZip序列化程序时遇到了一些奇怪的问题。
尝试序列化其中包含数据的对象。
下面的代码给出结果(在调试中的POINT1处):ms.Length = 100028和uncompressedStream.Length = 100027
在POINT1之后,有一个异常\“解析完成之前遇到的流结束。\”,我认为这是此丢失字节的结果。
我正在使用.net 4.0。
//generating data
int length = 100000;
byte[] data = new byte[length];
for (int i = 0; i < length; i++)
{
data[i] = System.Convert.ToByte(i % 100 + i % 50);
}
//serialization into memory stream
IFormatter formatter = new BinaryFormatter();
var ms = new MemoryStream();
formatter.Serialize(ms,data);
ms.Seek(0,SeekOrigin.Begin);
//GZip zip
MemoryStream compressedStream = new MemoryStream();
var Compress = new GZipStream(compressedStream,CompressionMode.Compress);
ms.copyTo(Compress);
compressedStream.Seek(0,SeekOrigin.Begin);
//GZip Unzip
MemoryStream uncompressedStream = new MemoryStream();
var Decompress = new GZipStream(compressedStream,CompressionMode.Decompress);
Decompress.copyTo(uncompressedStream);
uncompressedStream.Seek(0,SeekOrigin.Begin);
//deserialization from memory stream
//POINT1
var oo = formatter.Deserialize(uncompressedStream);
var o = (byte[])oo;
//checking
Assert.AreEqual(data.Length,o.Length);
for (int i = 0; i < data.Length; i++)
Assert.AreEqual(data[i],o[i]);
解决方法
压缩流在关闭之前不会冲洗(也无法正确冲洗)。您将需要关闭
GZipStream
。告诉它不要关闭基础流(构造函数参数之一)将使此操作更容易。
//generating data
int length = 100000;
byte[] data = new byte[length];
for (int i = 0; i < length; i++)
{
data[i] = System.Convert.ToByte(i % 100 + i % 50);
}
byte[] o;
//serialization into memory stream
IFormatter formatter = new BinaryFormatter();
using (var ms = new MemoryStream())
{
formatter.Serialize(ms,data);
ms.Seek(0,SeekOrigin.Begin);
//GZip zip
using(MemoryStream compressedStream = new MemoryStream())
{
using (var Compress = new GZipStream(compressedStream,CompressionMode.Compress,true))
{
ms.CopyTo(Compress);
}
compressedStream.Seek(0,SeekOrigin.Begin);
//GZip Unzip
using (MemoryStream uncompressedStream = new MemoryStream())
{
using (var Decompress = new GZipStream(compressedStream,CompressionMode.Decompress,true))
{
Decompress.CopyTo(uncompressedStream);
}
uncompressedStream.Seek(0,SeekOrigin.Begin);
var oo = formatter.Deserialize(uncompressedStream);
o = (byte[])oo;
}
}
//deserialization from memory stream
//POINT1
}
//checking
Debug.Assert(data.Length == o.Length);
for (int i = 0; i < data.Length; i++)
Debug.Assert(data[i] == o[i]);