所以我试图压缩一个字节数组(通过Stream)。 ExtendedStream只是我创建的一个与基本流接口的类(默认为MemoryStream)。如果我获取原始数据,压缩它,解压缩,然后将解压缩数据的大小与原始数据的大小(压缩前)进行比较,结果表明它小于原始数据。
原始长度:51695,压缩长度:26014,解压缩长度:48685。
我正在存储瓷砖(7个字节)。使用System.IO.Compression命名空间中提供的GZip类进行压缩。
public static ExtendedStream GZipDecompress(ExtendedStream stream)
{
ExtendedStream outStream = new ExtendedStream();
GZipStream decompressStream = new GZipStream(stream.BaseStream, CompressionMode.Decompress, true);
int b = -1;
while ((b = decompressStream.ReadByte()) != -1)
{
outStream.WriteByte((Byte)b);
}
outStream.Seek(0, SeekOrigin.Begin);
return outStream;
}
public static ExtendedStream GZipCompress(ExtendedStream stream)
{
ExtendedStream outStream = new ExtendedStream(); // base stream is a memorystream
GZipStream compressStream = new GZipStream(outStream.BaseStream, CompressionMode.Compress, true);
compressStream.Write(stream.ToArray(), 0, (int)stream.Length);
compressStream.Flush();
outStream.Seek(0, SeekOrigin.Begin);
return outStream;
}
希望有足够的信息。
答案 0 :(得分:1)
您必须关闭压缩流;由于块问题,它无法写入所有数据:
public static ExtendedStream GZipCompress(ExtendedStream stream)
{
ExtendedStream outStream = new ExtendedStream();
using(var compressStream = new GZipStream(outStream.BaseStream, CompressionMode.Compress, false)) {
compressStream.Write(stream.GetBuffer(), 0, (int)stream.Length);
}
outStream.Seek(0, SeekOrigin.Begin);
return outStream;
}
注意:通常我会使用CopyTo(或手动循环)来执行写操作,但由于这是基于内存的GetBuffer()更便宜。
您的减压可以简单地说:
decompressStream.WriteTo(outStream);
在这两个方面,最大的问题(在这里咬过你)并没有丢弃你的一次性物品。你必须这样做;这是API的要求。为避免过早地处置外部流,请将“false”传递给GZipStream构造函数。例如:
using(var decompressStream = new GZipStream(stream.BaseStream, CompressionMode.Decompress, false)) {
decompressionStream.CopyTo(outStream);
}