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
    {
      /// <summary>
      /// 输入缓冲区指针
      /// </summary>
      public IntPtr next_in;
      /// <summary>
      /// 输入缓冲去可用数据长度
      /// </summary>
      public int avail_in;
      /// <summary>
      /// 总输入字节数
      /// </summary>
      public int total_in;

      /// <summary>
      /// 输出缓冲区指针
      /// </summary>
      public IntPtr next_out;
      /// <summary>
      /// 输出缓冲可用长度
      /// </summary>
      public int avail_out;
      /// <summary>
      /// 总输出字节数
      /// </summary>
      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;
    }
    /// <summary>
    /// 压缩数据
    /// </summary>
    /// <param name="stream">压缩数据流</param>
    /// <param name="flush"></param>
    /// <returns></returns>
    [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);

    /// <summary>
    /// 这个函数在一些版本中不带下划线
    /// </summary>
    /// <param name="stream">流对象</param>
    /// <param name="level"></param>
    /// <param name="version">Zlib版本</param>
    /// <param name="nSize">流对象大小</param>
    /// <returns></returns>
    [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));
    }

    /// <summary>
    /// 压缩数据
    /// </summary>
    /// <param name="dest">压缩后的数据缓冲</param>
    /// <param name="destLen">压缩后的数据缓冲长度</param>
    /// <param name="source">压缩前的数据缓冲</param>
    /// <param name="sourceLen">压缩前的数据缓冲长度</param>
    /// <returns></returns>
    [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);

    /// <summary>
    /// 压缩数据
    /// </summary>
    /// <param name="src">压缩数据块</param>
    /// <param name="flush"></param>
    /// <returns>压缩后的数据</returns>
    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();
    }

    /// <summary>
    /// 解压数据
    /// </summary>
    /// <param name="dest">解压后的数据缓冲</param>
    /// <param name="destLen">解压后的数据缓冲长度</param>
    /// <param name="source">压缩的数据缓冲</param>
    /// <param name="sourceLen">压缩的数据缓冲长度</param>
    /// <returns></returns>
    [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);

    /// <summary>
    /// 解压数据
    /// </summary>
    /// <param name="src">压缩的数据缓冲</param>
    /// <returns>解压后的数据</returns>
    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();
    }

  }
}
复制代码

 

posted @   otoboku  阅读(865)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示