GZipstream压缩解压文件夹方法2

来源:互联网 发布:网店加盟淘宝货源 编辑:程序博客网 时间:2024/05/21 01:32

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 System.IO.Compression;

namespace WinAppTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private const string m_FileExtensionName = ".XXzip";  // hwzip compress file
        private const int m_MaxFileTotalLength = 1024 * 1024 * 1024;  // 1G
        private const int m_ReadBufferSize = 8 * 1024;  // 8K

        private string m_GZipFileName = string.Empty;
        private string m_FolderDecompressTo = string.Empty;

        private List<TGZipFileEntry> m_FileEntryList = new List<TGZipFileEntry>();
        private List<TGZipFileEntry> m_PacketEntryList = new List<TGZipFileEntry>();

        private byte[] m_ReadBuffer = new byte[m_ReadBufferSize];

        private int m_NowMaxBarValue = 0;

        private void btnOpen_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog browser = new FolderBrowserDialog();
            if (browser.ShowDialog() == DialogResult.OK)
            {
                txtPath.Text = browser.SelectedPath;
            }
        }

        private void btnCompress_Click(object sender, EventArgs e)
        {
            try
            {
                string filePath = txtPath.Text.Trim() + "//";
                string fileName = txtFileName.Text.Trim();
                if (filePath.Length == 0 || fileName.Length == 0) return;

               // GZipCompress.Compress(filePath, fileName);
                Compressing(fileName, filePath);
                MessageBox.Show("Success");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnOpenSaveAs_Click(object sender, EventArgs e)
        {
            SaveFileDialog save = new SaveFileDialog();
            save.AddExtension = true;
            save.Filter = "Gzip|*.Gzip";

            if (save.ShowDialog() == DialogResult.OK)
            {
                txtFileName.Text = save.FileName;
            }
        }


        //

        public bool AppendFile(string fileName)
        {
            if (string.IsNullOrEmpty(fileName) || !File.Exists(fileName))
            {
                MessageBox.Show("Zip FileName is empty or does not exist.");
                return false;
            }

            TGZipFileEntry addFileInfo = new TGZipFileEntry(fileName);
            long totalLength = addFileInfo.OriginalLength;

            foreach (TGZipFileEntry fileEntry in m_FileEntryList)
            {
                if (fileEntry.FileName.ToUpper() == addFileInfo.FileName.ToUpper())
                {
                    MessageBox.Show("File: " + fileEntry.FileName + " has exists.");
                    return false;
                }
                totalLength += fileEntry.OriginalLength;
            }

            if (totalLength > m_MaxFileTotalLength)
            {
                MessageBox.Show("Total files length is over " + (m_MaxFileTotalLength / (1024 * 1024)).ToString() + "M.");
                return false;
            }

            m_FileEntryList.Add(addFileInfo);
            return true;
        }

        private bool Compressing(string zipFileName,string path)
        {
            m_FileEntryList.Clear();

            foreach (string str in Directory.GetFiles(path))
            {
                AppendFile(str);
            }


            bool opSuccess = false;

            if (m_FileEntryList.Count == 0)
            {
                MessageBox.Show("There has no compress file.");
                return opSuccess;
            }
            m_GZipFileName = zipFileName;
            if (string.IsNullOrEmpty(m_GZipFileName))
            {
                MessageBox.Show("Zip FileName is empty or not set.");
                return opSuccess;
            }

            this.SetApplicationCursor(Cursors.WaitCursor);

            try
            {
                using (FileStream outStream = new FileStream(m_GZipFileName, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    this.m_PacketEntryList.Clear();
                    this.WriteHeaderEmptyInfo(outStream);  // 写文件长度字节, 压缩结束后再填实际数据
                    this.SetProgressBarMaxValue(false);
                    this.ShowBeginStep();

                    foreach (TGZipFileEntry fileEntry in m_FileEntryList)
                    {
                        this.SetProgressBarNowMaxValue(fileEntry, false);

                        fileEntry.WriteEntryInfo(outStream);
                        this.ShowProgressStep();
                        this.CompressFile(fileEntry, outStream);
                        this.m_PacketEntryList.Add(fileEntry);
                    }

                    this.WriteHeaderLengthInfo(outStream);  // 再填文件头, 此时有各块的长度信息
                }
                opSuccess = true;
            }
            catch (Exception err)
            {
                throw new Exception(err.Message);
            }
            finally
            {
                this.ShowFinalStep();
                this.SetApplicationCursor(Cursors.Default);
            }
            return opSuccess;
        }


        /// <summary>
        /// Compress one file.
        /// </summary>
        private void CompressFile(TGZipFileEntry fileEntry, Stream outStream)
        {
            long preStreamPosition = outStream.Position;

            using (FileStream srcStream = new FileStream(fileEntry.FileFullName, FileMode.Open, FileAccess.Read, FileShare.Read))
            using (GZipStream zipStream = new GZipStream(outStream, CompressionMode.Compress, true))
            {
                this.ShowProgressStep();

                int readCount = m_ReadBufferSize;
                while (readCount == m_ReadBufferSize)
                {
                    readCount = srcStream.Read(m_ReadBuffer, 0, m_ReadBufferSize);
                    zipStream.Write(m_ReadBuffer, 0, readCount);

                     this.ShowProgressStep();
                }
            }

            fileEntry.GZipFileLength = (int)(outStream.Position - preStreamPosition);  // 写入的长度
        }


        /// <summary>
        /// 写空头字节, 用于占位置
        /// </summary>
        private void WriteHeaderEmptyInfo(Stream outStream)
        {
            int headerSize = 1 + m_FileEntryList.Count * 3;  // 前4个字节是文件数, 每个文件3部分, 分别是: 原文件长、压缩后长、文件项长
            byte[] headerBytes = new byte[4 * headerSize];
            outStream.Write(headerBytes, 0, headerBytes.Length);
        }

        /// <summary>
        /// 写实际的文件数、文件长度、项长度字节
        /// </summary>
        private void WriteHeaderLengthInfo(Stream outStream)
        {
            byte[] fileCountBytes = BitConverter.GetBytes((int)m_PacketEntryList.Count);
            TCipher.EncryptBytes(fileCountBytes);

            outStream.Position = 0;
            outStream.Write(fileCountBytes, 0, fileCountBytes.Length);

            foreach (TGZipFileEntry entry in m_PacketEntryList)
            {
                entry.WriteLengthInfo(outStream);
            }
        }

        ///////////

        private bool Decompressing(string zipFileName,string decompressFolder)
        {
            bool opSuccess = false;
            m_FolderDecompressTo = decompressFolder;
            if (string.IsNullOrEmpty(m_FolderDecompressTo))
            {
                MessageBox.Show("Decompress folder is empty.");
                return opSuccess;
            }
            m_GZipFileName = zipFileName;
            if (string.IsNullOrEmpty(m_GZipFileName))
            {
                MessageBox.Show("Zip FileName is empty or does not exist.");
                return opSuccess;
            }

            this.SetApplicationCursor(Cursors.WaitCursor);

            try
            {
                using (FileStream srcStream = new FileStream(m_GZipFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    this.m_PacketEntryList.Clear();
                    this.ReadHeaderLengthInfo(srcStream);  // 获得各块的长度信息, 缺少文件项中的文件名、日期等信息
                    this.SetProgressBarMaxValue(true);
                    this.ShowBeginStep();

                    foreach (TGZipFileEntry fileEntry in m_PacketEntryList)
                    {
                        this.SetProgressBarNowMaxValue(fileEntry, true);

                        fileEntry.ReadEntryInfo(srcStream);  // 读当前项的日期、文件名信息
                        this.ShowProgressStep();
                        this.DecompressFile(srcStream, fileEntry);
                        fileEntry.ResetFileDateTime(m_FolderDecompressTo);
                    }
                }
                opSuccess = true;
            }
            catch (Exception err)
            {
                throw new Exception(err.Message);
            }
            finally
            {
                this.ShowFinalStep();
                this.SetApplicationCursor(Cursors.Default);
            }

            return opSuccess;
        }


        private void DecompressFile(Stream srcStream, TGZipFileEntry fileEntry)
        {
            using (FileStream outStream = new FileStream(this.m_FolderDecompressTo + fileEntry.FileName, FileMode.Create, FileAccess.Write, FileShare.None))
            using (MemoryStream memStream = new MemoryStream())
            using (GZipStream zipStream = new GZipStream(memStream, CompressionMode.Decompress, true))
            {
                int gzipFileLength = fileEntry.GZipFileLength;
                int readCount;
                while (gzipFileLength > 0)
                {
                    int maxCount = Math.Min(gzipFileLength, m_ReadBufferSize);

                    readCount = srcStream.Read(m_ReadBuffer, 0, maxCount);
                    memStream.Write(m_ReadBuffer, 0, readCount);

                    gzipFileLength -= readCount;

                    this.ShowProgressStep();
                }

                memStream.Position = 0;
                readCount = m_ReadBufferSize;
                while (readCount == m_ReadBufferSize)
                {
                    readCount = zipStream.Read(m_ReadBuffer, 0, m_ReadBufferSize);
                    outStream.Write(m_ReadBuffer, 0, readCount);

                    this.ShowProgressStep();
                }
            }
            this.ShowProgressStep();
        }

        private void ReadHeaderLengthInfo(Stream srcStream)
        {
            byte[] fileCountBytes = new byte[4];
            srcStream.Read(fileCountBytes, 0, fileCountBytes.Length);
            TCipher.EncryptBytes(fileCountBytes);

            int fileCount = BitConverter.ToInt32(fileCountBytes, 0);

            for (int k = 1; k <= fileCount; k++)
            {
                TGZipFileEntry entry = new TGZipFileEntry();
                entry.ReadLengthInfo(srcStream);
                m_PacketEntryList.Add(entry);
            }
        }

        private void btnDecompress_Click(object sender, EventArgs e)
        {
             try
            {
                string filePath = txtPath.Text.Trim();
                string fileName = txtFileName.Text.Trim();
                if (filePath.Length == 0 || fileName.Length == 0) return;

               // GZipCompress.Compress(filePath, fileName);
                Decompressing(fileName, filePath);
                MessageBox.Show("Success");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
           
        }

        /////////

        /// <summary>
        /// 设置当前控件及其全部父控件的光标
        /// </summary>
        private void SetApplicationCursor(Cursor cursor)
        {
            this.Cursor = cursor;
            Control parent = this.Parent;
            while (parent != null)
            {
                parent.Cursor = cursor;
                parent = parent.Parent;
            }
        }

        private void SetStartPosition()
        {
            this.progressBar1.Value = 0;
            this.progressBar1.Refresh();
        }

        private void ShowBeginStep()
        {
            this.progressBar1.Value += 1;
            this.progressBar1.Refresh();
        }

        private void ShowProgressStep()
        {
            if (this.progressBar1.Value + 1 < m_NowMaxBarValue)
            {
                this.progressBar1.Value += 1;
            }
        }

        private void ShowFinalStep()
        {
            while (this.progressBar1.Value + 1 < this.progressBar1.Maximum)
            {
                this.progressBar1.Value += 1;
            }
            this.progressBar1.Value = this.progressBar1.Maximum;
            this.progressBar1.Refresh();
        }

        private int GetFileMaxStepLength(TGZipFileEntry fileEntry, bool decompress)
        {
            int maxLength = Math.Max(fileEntry.OriginalLength, fileEntry.GZipFileLength);
            int stepValue = 0;

            if (decompress)
            {
                stepValue++;  // 取文件项
                stepValue += 2 * (maxLength / m_ReadBufferSize);  // 产生压缩流
                stepValue++;  // 关闭文件
            }
            else
            {
                stepValue++;  // 打开源文件
                stepValue++;  // 写文件信息项
                stepValue += maxLength / m_ReadBufferSize;  // 压缩
            }

            return stepValue;
        }

        private void SetProgressBarMaxValue(bool decompress)
        {
            this.SetStartPosition();
            m_NowMaxBarValue = 0;

            int maxBarValue = 1;  // 打开/建立文件
            if (decompress)
            {
                foreach (TGZipFileEntry fileEntry in m_PacketEntryList)
                {
                    maxBarValue += this.GetFileMaxStepLength(fileEntry, decompress);  // 加每个文件的步长
                }
            }
            else
            {
                foreach (TGZipFileEntry fileEntry in m_FileEntryList)
                {
                    maxBarValue += this.GetFileMaxStepLength(fileEntry, decompress);  // 加每个文件的步长
                }
            }
            maxBarValue += 1;  // 最后收尾
            this.progressBar1.Maximum = maxBarValue;
        }

        private void SetProgressBarNowMaxValue(TGZipFileEntry fileEntry, bool decompress)
        {
            m_NowMaxBarValue += this.GetFileMaxStepLength(fileEntry, decompress);
        }

    }
}

原创粉丝点击