C# · 12月 28, 2021

c# – GZipStream压缩问题(Lost Byte)

我有一个奇怪的问题,GZip Serializer.

尝试用数据序列化对象.

以下代码给出结果(在调试中的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]);