⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lz77.cs

📁 自己写的可扩展插件文件管理器
💻 CS
字号:
using System;
using System.IO;
/////////////////////////////////////
// lz77压缩算法
/////////////////////////////////////
namespace lz77lib
{
    public class lz77
    {
        public lz77()
        { }

        #region 压缩数据
        public static void zipData(FileStream data, FileStream zipedData)
        { /////////////////////////////////
            // 初始化变量
            /////////////////////////////////
           // FileStream data = new FileStream(souce, FileMode.Open);
            //FileStream zipedData = new FileStream(target, FileMode.Create);
            int p, wPos, wLen, tPos, tLen;
            int dataLength = (int)data.Length;
            int bufferLength = 0;
            byte[] buffer = new byte[4096];
            byte[] buffer_zip = new byte[8092];
            int[] nextSamePoint = new int[4096];
            int bufferDP;
            bool f, ff;
            byte tByteLen = 0;
            int tInt = 0;
            /////////////////////////////////
            // 开始分组压缩
            /////////////////////////////////
            while ((bufferLength = data.Read(buffer, 0, 4096)) > 0)
            { // 如果buffer长度太短直接保存
                if (bufferLength < 6)
                {
                    for (int i = 0; i < Math.Min(3, bufferLength); i++)
                    {
                        tInt = (tInt << 8) + buffer[i];
                        zipedData.WriteByte((byte)(tInt >> tByteLen));
                        tInt = getRightByte(tInt, tByteLen);
                    } for (int i = 3; i < bufferLength; i++)
                    {
                        tInt = (tInt << 9) + buffer[i];
                        tByteLen += 9;
                        while (tByteLen >= 8)
                        {
                            zipedData.WriteByte((byte)(tInt >> (tByteLen -= 8) << 24 >> 24));
                        } tInt = getRightByte(tInt, tByteLen); // 记录剩余信息
                    } break;
                } // 提前计算出下一个相同字节的位置
                for (int i = 0; i < bufferLength; i++)
                {
                    for (int j = i + 1; j < bufferLength; j++)
                    {
                        nextSamePoint[i] = 4096;
                        if (buffer[i] == buffer[j])
                        {
                            nextSamePoint[i] = j;
                            break;
                        }
                    }
                } // 初始化字典和滑块
                tInt = (tInt << 8) + buffer[0];
                buffer_zip[0] = (byte)(tInt >> tByteLen);
                tInt = getRightByte(tInt, tByteLen);
                tInt = (tInt << 8) + buffer[1];
                buffer_zip[1] = (byte)(tInt >> tByteLen);
                tInt = getRightByte(tInt, tByteLen);
                tInt = (tInt << 8) + buffer[2];
                buffer_zip[2] = (byte)(tInt >> tByteLen);
                tInt = getRightByte(tInt, tByteLen);
                p = 3;
                wPos = 0;
                wLen = 3;
                tPos = -1;
                tLen = 0;
                bufferDP = 2;
                ////////////////////////////////
                // 开始编码
                ////////////////////////////////
                while (bufferLength - 3 >= p)
                {
                    while (wPos + wLen <= p && p + wLen <= bufferLength)
                    { // 判断滑块是否匹配
                        f = true;
                        if (buffer[wPos] == buffer[p])
                        {
                            ff = true;
                            for (int i = 1; i < wLen; i++)
                            {
                                if (buffer[wPos + i] != buffer[p + i])
                                {
                                    f = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            f = false;
                            ff = false;
                        } // 匹配则增加滑块长度,否则移动
                        if (!f)
                        { // 滑块移动
                            if (ff)
                            {
                                wPos = nextSamePoint[wPos];
                            }
                            else
                            {
                                wPos++;
                            }
                        }
                        else
                        { // 增加滑块长度
                            while (wPos + wLen != p && p + wLen != bufferLength && wLen < 1024)
                            {
                                if (buffer[wPos + wLen] == buffer[p + wLen])
                                {
                                    wLen++;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            tPos = wPos;
                            tLen = wLen;
                            // 滑块移动并增加1长度
                            wPos = nextSamePoint[wPos];
                            wLen++;
                        }
                    }
                    //////////////////////////////////
                    // 写入buffer_zip
                    //////////////////////////////////
                    if (tPos == -1)
                    { // 单个字节
                        tInt = (tInt << 9) + buffer[p];
                        tByteLen += 9;
                        p++;
                    }
                    else
                    { // 匹配的字节串
                        tInt = (((tInt << 1) + 1 << 12) + tPos << 11) + tLen;
                        tByteLen += 24;
                        p += tLen;
                    } while (tByteLen >= 8)
                    {
                        buffer_zip[++bufferDP] = (byte)(tInt >> (tByteLen -= 8) << 24 >> 24);
                    } tInt = getRightByte(tInt, tByteLen); // 记录剩余信息
                    ////////////////////////////////////
                    // 初始化滑块
                    ////////////////////////////////////
                    wPos = 0;
                    wLen = 3;
                    tPos = -1;
                    tLen = 0;
                } // 写入剩余字节
                for (int i = p; i < bufferLength; i++)
                {
                    tInt = (tInt << 9) + buffer[i];
                    tByteLen += 9;
                    buffer_zip[++bufferDP] = (byte)(tInt >> (tByteLen -= 8));
                    tInt = getRightByte(tInt, tByteLen);
                } // 写入Stream
                zipedData.Write(buffer_zip, 0, bufferDP + 1);
            } if (tByteLen != 0) zipedData.WriteByte((byte)(tInt << 8 - tByteLen)); // 写入剩余信息
            data.Close();
            zipedData.Close();
        }
        #endregion
        #region 解压数据
        public static void unzipData(string souceFilePath, long pos, string targetFilePath)
        { /////////////////////////////////
            // 初始化变量
            /////////////////////////////////
            FileStream zipedData = new FileStream(souceFilePath, FileMode.Open);
            FileStream data = new FileStream(targetFilePath, FileMode.Create);
            zipedData.Seek(pos, SeekOrigin.Begin);
            uint wPos = 0, wLen = 0;
            int buffer_zipLength = (int)zipedData.Length;
            byte[] buffer = new byte[4096];
            byte[] buffer_zip = new byte[buffer_zipLength];
            int buffer_zipDP = -1;
            int bufferDP = -1;
            byte tByteLen = 0;
            uint tInt = 0;
            zipedData.Read(buffer_zip, 0, buffer_zipLength);
            /////////////////////////////////
            // 开始解压
            /////////////////////////////////
            while (buffer_zipDP < buffer_zipLength - 3)
            { // 写入前3个字节
                tInt = (tInt << 8) + buffer_zip[++buffer_zipDP];
                buffer[0] = (byte)(tInt >> tByteLen);
                tInt = getRightByte(tInt, tByteLen);
                tInt = (tInt << 8) + buffer_zip[++buffer_zipDP];
                buffer[1] = (byte)(tInt >> tByteLen);
                tInt = getRightByte(tInt, tByteLen);
                tInt = (tInt << 8) + buffer_zip[++buffer_zipDP];
                buffer[2] = (byte)(tInt >> tByteLen);
                tInt = getRightByte(tInt, tByteLen);
                bufferDP = 2;
                while (bufferDP < 4095)
                { // 读入充足数据
                    while (tByteLen < 24 && buffer_zipDP < buffer_zipLength - 1)
                    {
                        tInt = (tInt << 8) + buffer_zip[++buffer_zipDP];
                        tByteLen += 8;
                    } // 写入buffer
                    if (tInt >> tByteLen - 1 == 0)
                    { // 单个字节
                        tByteLen -= 1;
                        tInt = getRightByte(tInt, tByteLen);
                        buffer[++bufferDP] = (byte)(tInt << 32 - tByteLen >> 24);
                        tByteLen -= 8;
                        tInt = getRightByte(tInt, tByteLen);
                    }
                    else
                    { // 字节串
                        tByteLen -= 1;
                        tInt = getRightByte(tInt, tByteLen);
                        wPos = tInt >> (tByteLen -= 12);
                        tInt = getRightByte(tInt, tByteLen);
                        wLen = tInt >> (tByteLen -= 11);
                        tInt = getRightByte(tInt, tByteLen);
                        for (int i = 0; i < wLen; i++)
                        {
                            buffer[++bufferDP] = buffer[wPos + i];
                        }
                    }
                    // 判断是否解压完成
                    if (buffer_zipDP == buffer_zipLength - 1 && tByteLen < 9) break;
                } // 写入Stream
                data.Write(buffer, 0, bufferDP + 1);
            } // 写入剩余的信息
            for (int i = buffer_zipDP + 1; i < buffer_zipLength; i++)
            {
                data.WriteByte(buffer_zip[i]);
            } zipedData.Close();
            data.Close();
        } 
        #endregion
        #region private item
        private static int getLeftByte(int dataLine, int s)
        {
            return dataLine << 32 - s >> 24;
        }
        private static uint getLeftByte(uint dataLine, int s)
        {
            return dataLine << 32 - s >> 24;
        }
        private static int getRightByte(int dataLine, int l)
        {
            if (l == 0)
            {
                return 0;
            }
            else
            {
                return dataLine << (32 - l) >> (32 - l);
            }
        }
        private static uint getRightByte(uint dataLine, int l)
        {
            if (l == 0)
            {
                return 0;
            }
            else
            {
                return dataLine << (32 - l) >> (32 - l);
            }
        }
    }
}
#endregion

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -