相關原理
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://stackoverflow.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();
}