相关原理
deflate(RFC1951):一种压缩算法,使用LZ77和哈弗曼进行编码;
zlib(RFC1950):一种格式,是对deflate进行了简单的封装,他也是一个实现库(delphi中有zlib,zlibex)
gzip(RFC1952):一种格式,也是对deflate进行的封装。
gzip = gzip头 + deflate编码的实际内容 + gzip尾
zlib = zlib头 + deflate编码的实际内容 + zlib尾
deflate 压缩会在前缀加上78 9C 或者78 XX 的标志位。后尾也是4个校验标志。
- 尾部分
CRC32:4字节。原始(未压缩)数据的32位校验和。
ISIZE:4字节。原始(未压缩)数据的长度的低32位。
GZIP中字节排列顺序是LSB方式,即Little-Endian,与ZLIB中的相反。
https://blog.csdn.net/rainharder/article/details/26342919
用于c#的开源代码
ZLIB.NET Free v.1.04 Free
http://www.componentace.com/download/download.php?editionid=25
这里面有示例,压缩和解压一个文件。
其中根据压缩等级不同,其前缀标志位不同。可以编辑看看。
原始在这https://www.zlib.net/
来自这里https://blog.csdn.net/jiangxinyu/article/details/3732474
public override byte[] Compress( byte[] inputBytes,int level )
{
using ( MemoryStream ms = new MemoryStream() ) {
using ( ZOutputStream zOut = new ZOutputStream( ms, level ) ) {
zOut.Write( inputBytes, 0, inputBytes.Length );
zOut.finish();
return ms.ToArray();
}
}
}
public override byte[] Decompress( byte[] inputBytes )
{
using ( MemoryStream ms = new MemoryStream() ) {
using ( ZOutputStream zOut = new ZOutputStream( ms ) ) {
zOut.Write( inputBytes, 0, inputBytes.Length );
zOut.finish();
return ms.ToArray();
}
}
}
/// <summary>
/// 压缩数据集
/// </summary>
/// <param name="ds"></param>
/// <returns></returns>
public static byte[] CompressDS(DataSet ds)
{
MemoryStream ms = new MemoryStream();
ZipOutputStream zos = new ZipOutputStream(ms);
zos.PutNextEntry(new ZipEntry(ds.DataSetName));
BinaryFormatter bf = new BinaryFormatter();
DataSetSurrogate dss = new DataSetSurrogate(ds);
bf.Serialize(zos, dss);
zos.CloseEntry();
zos.Close();
byte[] ret = ms.ToArray();
ms.Close();
return ret;
}
/// <summary>
/// 解压数据集
/// </summary>
/// <param name="byt"></param>
/// <returns></returns>
public static DataSet DecompressDS(byte[] byt)
{
MemoryStream ms = new MemoryStream(byt);
BinaryFormatter bf = new BinaryFormatter();
ZipInputStream zis = new ZipInputStream(ms);
zis.GetNextEntry();
DataSetSurrogate dss = (DataSetSurrogate)bf.Deserialize(zis);
zis.Close();
ms.Close();
DataSet ds = dss.ConvertToDataSet();
return ds;
}
zlib.net.dll中自带的例子
private void compressFile(string inFile, string outFile)
{
System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION);
System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);
try
{
CopyStream(inFileStream, outZStream);
}
finally
{
outZStream.Close();
outFileStream.Close();
inFileStream.Close();
}
}
private void decompressFile(string inFile, string outFile)
{
System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream);
System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);
try
{
CopyStream(inFileStream, outZStream);
}
finally
{
outZStream.Close();
outFileStream.Close();
inFileStream.Close();
}
}
https://*.com/questions/6620655/compression-and-decompression-problem-with-zlib-net
老外这也有一份
public static void CompressData(byte[] inData, out byte[] outData)
{
using (MemoryStream outMemoryStream = new MemoryStream())
using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream, zlibConst.Z_DEFAULT_COMPRESSION))
using (Stream inMemoryStream = new MemoryStream(inData))
{
CopyStream(inMemoryStream, outZStream);
outZStream.finish();
outData = outMemoryStream.ToArray();
}
}
public static void DecompressData(byte[] inData, out byte[] outData)
{
using (MemoryStream outMemoryStream = new MemoryStream())
using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream))
using (Stream inMemoryStream = new MemoryStream(inData))
{
CopyStream(inMemoryStream, outZStream);
outZStream.finish();
outData = outMemoryStream.ToArray();
}
}
public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[2000];
int len;
while ((len = input.Read(buffer, 0, 2000)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
}