代码改变世界

zlib压缩相关

2019-07-23 10:58  撞破南墙  阅读(1514)  评论(0编辑  收藏  举报

相关原理

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个校验标志。

  1. 尾部分
    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();
}