多线程、委托、事件的范本

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using BinaryRW;
using System.Threading;


namespace CC1
{
    public partial class Form1 : Form
    {
        delegate void UpdateDelegate(int ct);
        event UpdateDelegate UpdateEvent;
        delegate void FinishedDelegate();
        event FinishedDelegate FinishedEvent;


        string source, destination;
        int sourcesize, destinationsize;
        BinaryRW.BinaryRW reader, writer;


        bool compress;


        int L, P, B;


        public Form1()
        {
            InitializeComponent();
            UpdateEvent = UpdatePB;
        }


        //--------------------------BUTTONS-----------------------------------//
        private void btnSelFile_Click(object sender, EventArgs e)
        {
            btnCompress.Enabled = btnDecompress.Enabled = false;


            OpenFileDialog odlg = new OpenFileDialog();
            odlg.CheckFileExists = true;
            if (odlg.ShowDialog() == DialogResult.OK)
            {
                source = odlg.FileName;
                string extension = Path.GetExtension(source);
                if (extension == ".lz77")
                {
                    compress = false;
                    btnDecompress.Enabled = true;
                    nudBuffer.Enabled = nudLen.Enabled = nudPos.Enabled = false;
                    destination = Path.GetFileNameWithoutExtension(source);
                    destination = Path.GetFileNameWithoutExtension(destination) + "_dcd" + Path.GetExtension(destination);
                }
                else
                {
                    compress = true;
                    btnCompress.Enabled = true;
                    nudBuffer.Enabled = nudLen.Enabled = nudPos.Enabled = true;
                    destination = source + ".lz77";
                    //destination = source.Substring(0, source.LastIndexOf(@"."))+@".zip";
                }
                sourcesize = (int)(new System.IO.FileInfo(source).Length);
                lblOutput.Text = "";
            }
        }
        private void btnCompress_Click(object sender, EventArgs e)
        {
            InitForCompress();
            //Compress();
            Thread t = new Thread(Compress);
            t.Start();
        }
        private void btnDecompress_Click(object sender, EventArgs e)
        {
            InitForDecompress();
            //Decompress();
            Thread t = new Thread(Decompress);
            t.Start();
        }
        private void InitForCompress()
        {
            btnCompress.Enabled = false;
            nudBuffer.Enabled = nudLen.Enabled = nudPos.Enabled = false;
            btnSelFile.Enabled = false;
            L = (int)nudLen.Value;
            P = (int)nudPos.Value;
            B = (int)nudBuffer.Value;
            pbProgress.Maximum = sourcesize;
            FinishedEvent = FinishedCompress;
        }
        private void InitForDecompress()
        {
            btnDecompress.Enabled = false;
            btnSelFile.Enabled = false;
            pbProgress.Maximum = sourcesize * 8;
            FinishedEvent = FinishedDecompress;
        }
        //-------------------------THREADS------------------------//
        private void Compress()
        {
            BinaryReader br = new BinaryReader(File.Open(source, FileMode.Open));
            writer = new BinaryRW.BinaryRW(destination, false);
            //header
            writer.WriteByte((byte)P);
            writer.WriteByte((byte)L);
            
            List<byte> buffer = new List<byte>();
            bool lastread = false;
            int MaxL = 1<<L;
            int MaxP = 1<<P;
            int BR;
            int pos;


            buffer.AddRange(br.ReadBytes(B * 1024));
            BR = buffer.Count;
            if (BR < B * 1024) lastread = true;


            pos = 0;
            while (pos<BR)
            {
                //start looking for sequence
                int l = 0;
                //max left to go
                int SBL = Math.Min(MaxP, pos);
                //list of positions of sequences
                List<int> p = new List<int>();
                //init with first appearences
                for (int i = 0; i < SBL; i++)
                {
                    if (buffer[pos - (i + 1)] == buffer[pos])
                        p.Add(i);
                }
                if (p.Count == 0)
                {
                    //new character
                    //write to file
                    //flag
                    writer.WriteBit(1);
                    //character
                    writer.WriteBits(buffer[pos], 8);


                    //step forward
                    pos++;
                    if (UpdateEvent != null) UpdateEvent(1);
                }
                else
                {
                    l=1;
                    while (pos+l<BR && l<MaxL-1)
                    {
                        //tempp stores sequences of length l+1
                        List<int> tempp = new List<int>();
                        foreach (int i in p)
                        {
                            if (buffer[pos - (i + 1) + l] == buffer[pos + l])
                                tempp.Add(i);
                        }
                        if (tempp.Count == 0) break;//didnt find sequences of l+1 length
                        else
                        {
                            //select only the sequences of length l+1
                            p.Clear();
                            p.AddRange(tempp);
                            //go on
                            l++;
                        }
                    }
                    //found a l length sequence
                    //write to file
                    //flag
                    writer.WriteBit(0);
                    //pos
                    writer.WriteBits(p[0], P);
                    //lenght
                    writer.WriteBits(l, L);


                    //step forward
                    pos += l;
                    if (UpdateEvent != null) UpdateEvent(l);
                }
                //check if we're too close to the end of buffer
                if (pos >= BR-MaxP && !lastread)
                {
                    //try and read more
                    byte[] tempbuffer = br.ReadBytes(B * 1024);
                    //if no more signal it
                    if (tempbuffer.Length == 0)
                        lastread = true;
                    else
                    {
                        //add bytes read
                        List<byte> tempbuffer2 = new List<byte>();
                        for (int i = pos - SBL; i < BR; i++)
                            tempbuffer2.Add(buffer[i]);
                        buffer = tempbuffer2;
                        buffer.AddRange(tempbuffer);
                        BR = buffer.Count;
                        pos = SBL;
                    }
                }                
            }
            //end sequence
            //flag
            writer.WriteBit(1);
            //character
            writer.WriteBits(buffer[pos - 1], 8);


            writer.Close();
            br.Close();
            if (FinishedEvent != null) FinishedEvent();
        }


        private void Decompress()
        {
            reader = new BinaryRW.BinaryRW(source, true);
            BinaryWriter bw = new BinaryWriter(File.Create(destination));
            P = (int)reader.ReadByte();
            L = (int)reader.ReadByte();


            List<byte> buffer = new List<byte>();


            int MaxL = 1 << L;
            int MaxP = 1 << P;
            int BR = 0;
            int pos = 0;


            while (true)
            {
                int flag = reader.ReadBit();
                if (flag == 1)
                {
                    //new character
                    byte character = (byte)reader.ReadBits(8);
                    //end of stream
                    if(buffer.Count!=0)
                        if (character == buffer[pos]) 
                            break;
                    buffer.Add(character);
                    bw.Write(character);
                    if (UpdateEvent != null) UpdateEvent(9);
                }
                else
                {
                    //sequence
                    int position = reader.ReadBits(P);
                    int length = reader.ReadBits(L);
                    for (int i = 0; i < length; i++)
                    {
                        bw.Write(buffer[pos - position + i]);
                        buffer.Add(buffer[pos - position + i]);
                    }
                    if (UpdateEvent != null) UpdateEvent(P + L + 1);
                }
                BR = buffer.Count - 1;
                if (BR > MaxP)
                {
                    for (int i = MaxP; i < BR; i++)
                        buffer.RemoveAt(0);
                }
                BR = buffer.Count - 1;
                pos = BR;
            }


            reader.Close();
            bw.Close();
            if (FinishedEvent != null) FinishedEvent();
        }
        //-------------------------EVENTS-----------------------//
        private void UpdatePB(int ct)
        {
            Invoke(new MethodInvoker(delegate ()
            {
                pbProgress.Value += ct;
            }));
               
        }
        private void FinishedCompress()
        {
            Invoke(new MethodInvoker(delegate ()
            {
                btnCompress.Enabled = true;
                nudBuffer.Enabled = nudLen.Enabled = nudPos.Enabled = true;
                btnSelFile.Enabled = true;
                pbProgress.Value = 0;
            }));


            
            destinationsize = (int)(new System.IO.FileInfo(destination).Length);


            Invoke(new MethodInvoker(delegate ()
            {
                lblOutput.Text = sourcesize + " >> " + destinationsize;
            }));


            
        }
        private void FinishedDecompress()
        {
            Invoke(new MethodInvoker(delegate ()
            {
                btnDecompress.Enabled = true;
                btnSelFile.Enabled = true;
                pbProgress.Value = 0;
            }));


            
            destinationsize = (int)(new System.IO.FileInfo(destination).Length);


            Invoke(new MethodInvoker(delegate ()
            {
                lblOutput.Text = sourcesize + " >> " + destinationsize;
            }));
           
        }
        //-------------------------EXTRA---------------------------//
        
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值