所以我试图压缩一个字节数组(通过流)。 ExtendedStream 只是我创建的一个与基本流(默认为 MemoryStream)接口(interface)的类。如果我获取原始数据,压缩它,解压缩它,然后将解压缩数据的大小与原始数据的大小(压缩前)进行比较,结果发现它比原始数据小。
原始长度:51695,压缩长度:26014,解压长度:48685。
我正在存储图 block (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;
}
希望这是足够的信息。
最佳答案
您必须关闭压缩流;由于 block 问题,在您执行之前它无法写入所有数据:
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);
}
关于c# - 原始文件比 GZip 解压文件大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9434626/