C#使用ZLIB


using System;
using System.IO;
using System.Runtime.InteropServices;

namespace ConsoleApp1
{
  /*
  Zlib包装类,需要开启不安全代码编译
  static void Main(string[] args)
  {
    byte[] src = Encoding.UTF8.GetBytes("Test");
    byte[] dst = Zlib.compress(src);

    byte[] temp = Zlib.uncompress(dst);
    string t = Encoding.UTF8.GetString(temp);
    Console.WriteLine(t);
    Console.ReadKey();
  }
   */
  internal static class Zlib
  {
    [StructLayout(LayoutKind.Sequential)]
    private struct z_stream
    {
      /// 
      /// 输入缓冲区指针
      /// 
      public IntPtr next_in;
      /// 
      /// 输入缓冲去可用数据长度
      /// 
      public int avail_in;
      /// 
      /// 总输入字节数
      /// 
      public int total_in;

      /// 
      /// 输出缓冲区指针
      /// 
      public IntPtr next_out;
      /// 
      /// 输出缓冲可用长度
      /// 
      public int avail_out;
      /// 
      /// 总输出字节数
      /// 
      public int total_out;

      public IntPtr msg;
      public IntPtr state;

      public IntPtr zalloc;
      public IntPtr zfree;
      public IntPtr opaque;

      public int data_type;

      public uint adler;
      public uint reserved;
    }
    /// 
    /// 压缩数据
    /// 
    /// 压缩数据流
    /// 
    /// 
    [DllImport("zlib1.dll", EntryPoint = "deflate", CallingConvention = CallingConvention.Cdecl)]
    private static extern int deflate(ref z_stream stream, int flush = 4);

    [DllImport("zlib1.dll", EntryPoint = "inflate", CallingConvention = CallingConvention.Cdecl)]
    private static extern int inflate(ref z_stream stream, int flush = 4);

    [DllImport("zlib1.dll", EntryPoint = "zlibVersion", CallingConvention = CallingConvention.Cdecl)]
    private static extern IntPtr zlibVersion();

    [DllImport("zlib1.dll", EntryPoint = "deflateEnd", CallingConvention = CallingConvention.Cdecl)]
    private static extern IntPtr deflateEnd(ref z_stream stream);
    [DllImport("zlib1.dll", EntryPoint = "inflateEnd", CallingConvention = CallingConvention.Cdecl)]
    private static extern IntPtr inflateEnd(ref z_stream stream);

    /// 
    /// 这个函数在一些版本中不带下划线
    /// 
    /// 流对象
    /// 
    /// Zlib版本
    /// 流对象大小
    /// 
    [DllImport("zlib1.dll", EntryPoint = "deflateInit_", CallingConvention = CallingConvention.Cdecl)]
    private static extern int deflateInit(ref z_stream stream, int level, IntPtr version, int nSize);

    private static int deflateInit(ref z_stream stream, int level = -1)
    {
      return deflateInit(ref stream, level, zlibVersion(), Marshal.SizeOf(stream));
    }

    [DllImport("zlib1.dll", EntryPoint = "inflateInit_", CallingConvention = CallingConvention.Cdecl)]
    private static extern int inflateInit(ref z_stream stream, IntPtr version, int nSize);

    private static int inflateInit(ref z_stream stream)
    {
      return inflateInit(ref stream, zlibVersion(), Marshal.SizeOf(stream));
    }

    /// 
    /// 压缩数据
    /// 
    /// 压缩后的数据缓冲
    /// 压缩后的数据缓冲长度
    /// 压缩前的数据缓冲
    /// 压缩前的数据缓冲长度
    /// 
    [DllImport("zlib1.dll", EntryPoint = "compress", CallingConvention = CallingConvention.Cdecl)]
    public static extern int compress([MarshalAs(UnmanagedType.LPArray)] byte[] dest, out int destLen,
                            [MarshalAs(UnmanagedType.LPArray)] byte[] source, int sourceLen);

    /// 
    /// 压缩数据
    /// 
    /// 压缩数据块
    /// 
    /// 压缩后的数据
    public static byte[] compress(byte[] src)
    {
      var stream = new z_stream();
      var ret = new MemoryStream();


      deflateInit(ref stream);
      unsafe
      {
        byte[] dst = new byte[4096];
        fixed (byte* psrc = src, pdst = dst)
        {
          stream.avail_in = src.Length;
          stream.next_in = new IntPtr(psrc);

          while (true)
          {
            stream.avail_out = dst.Length;
            stream.next_out = new IntPtr(pdst);
            deflate(ref stream, 4);

            if (stream.avail_out == dst.Length)
            {
              break;
            }
            ret.Write(dst, 0, dst.Length - stream.avail_out);
          }
        }
      }
      deflateEnd(ref stream);

      return ret.ToArray();
    }

    /// 
    /// 解压数据
    /// 
    /// 解压后的数据缓冲
    /// 解压后的数据缓冲长度
    /// 压缩的数据缓冲
    /// 压缩的数据缓冲长度
    /// 
    [DllImport("zlib1.dll", EntryPoint = "uncompress", CallingConvention = CallingConvention.Cdecl)]
    public static extern int uncompress([MarshalAs(UnmanagedType.LPArray)] byte[] dest, out int destLen,
                            [MarshalAs(UnmanagedType.LPArray)] byte[] source, int sourceLen);

    /// 
    /// 解压数据
    /// 
    /// 压缩的数据缓冲
    /// 解压后的数据
    public static byte[] uncompress(byte[] src)
    {
      var stream = new z_stream();
      var ret = new MemoryStream();


      inflateInit(ref stream);
      unsafe
      {
        byte[] dst = new byte[4096];
        fixed (byte* psrc = src, pdst = dst)
        {
          stream.avail_in = src.Length;
          stream.next_in = new IntPtr(psrc);

          while (true)
          {
            stream.avail_out = dst.Length;
            stream.next_out = new IntPtr(pdst);
            inflate(ref stream, 4);

            if (stream.avail_out == dst.Length)
            {
              break;
            }
            ret.Write(dst, 0, dst.Length - stream.avail_out);
          }
        }
      }
      inflateEnd(ref stream);

      return ret.ToArray();
    }

  }
}
C