使用带有进度报告的 C# 提取 ZipFile [英] Extract ZipFile Using C# With Progress Report

查看:17
本文介绍了使用带有进度报告的 C# 提取 ZipFile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以告诉我是否有可能(并举一个例子)如何让进度条(如果可能,还有状态标签)显示使用ZipFile"(Ionic.zip)提取的 ZIP 文件的进度.zip,http://dotnetzip.codeplex.com/)?

Can anyone tell me if it is possible(and give an example if it is) on how to have a progress bar(and status label if possible) showing the progress of a ZIP file being extracted using "ZipFile"(Ionic.zip, http://dotnetzip.codeplex.com/)?

我的 WinForm 在将 ZIP 文件从我选择的路径提取到新路径方面做得很好,不用担心使用文本框和浏览按钮以及所有爵士乐......但是唯一的问题是我不能在我的表单上使用任何东西这段时间好像冻结了一样,只是因为它在后台解压了ZIP文件.

My WinForm does a great job at extracting a ZIP file from my chosen path to a new path no worries at all using textboxes and browse buttons and all that jazz... However the only issue is i cannot use anything on my form during this time it is as if it has frozen, but its only because its unzipping the ZIP file in the background.

ZIP 文件是一个大文件,我想通过添加并使用进度条来显示解压过程和准确的 ETA 来减少对正在发生的事情的混淆.

The ZIP file is a big file and i would like to make it less confusing on what is going on by adding and having a progress bar showing how the unzipping is going with a accurate ETA.

这当然是可能的,我只是不知道如何在 C# WinForms 中做到这一点,我在网络上有相当不错的外观,却没有真正找到适合我的示例.

Surely this is possible, i just cannot work out how to do it in C# WinForms, i have had a fairly decent look all around the net without really being able to come across a example i can find suitable for me.

这是我所拥有的粗略示例:

Here is a rough example of what i have:

private void button1_Click(object sender, EventArgs e)
{
    var ROBOT0007 = textBox1.Text + @"\" + "ROBOT0007"; //ROBOT0007 folder
    var ROBOT_INSTALL = textBox1.Text + @"\" + "911" + @"\" + "files"; //ROBOT0007/911/files
    var ROBOT_INSTALL_SPECIAL = ROBOT_INSTALL + @"\" + "special.rar";  //ROBOT0007/911/files/special.rar

    //If the path has text...
    if (textBox1.TextLength > 0)
    {
        //if the subfolder doesn't exist then make it.
        if (!Directory.Exists(ROBOT0007))
        {
            Directory.CreateDirectory(ROBOT0007);
        }

        //if the textbox directory exists
        if (Directory.Exists(ROBOT0007))
        {
            using (ZipFile zip = ZipFile.Read(ROBOT_INSTALL_SPECIAL))
            {
                zip.ExtractAll(ROBOT0007, ExtractExistingFileAction.OverwriteSilently);

            } 
        }
    }
}

更新(04/11/2014):我已经删除了文本框,现在回到简单的基础,以下与后台工作人员一起工作,但是取消按钮对 RAR 文件没有影响......有什么建议吗?

UPDATE(04/11/2014): I have removed the textbox for now gone back to simple basics, the following works with a background worker, however the cancel button has no effect on RAR files... any advice?

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

namespace BackgroundWorkerSample
{
    // The BackgroundWorker will be used to perform a long running action
    // on a background thread.  This allows the UI to be free for painting
    // as well as other actions the user may want to perform.  The background
    // thread will use the ReportProgress event to update the ProgressBar
    // on the UI thread.
    public partial class Form1 : Form
    {
        /// <summary>
        /// The backgroundworker object on which the time consuming operation 
        /// shall be executed
        /// </summary>
        BackgroundWorker backgroundWorker1;

        public Form1()
        {
            InitializeComponent();
            backgroundWorker1 = new BackgroundWorker();

            // Create a background worker thread that ReportsProgress &
            // SupportsCancellation
            // Hook up the appropriate events.
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler
                    (backgroundWorker1_ProgressChanged);
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                    (backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
        }

        /// <summary>
        /// On completed do the appropriate task
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // The background process is complete. We need to inspect
            // our response to see if an error occurred, a cancel was
            // requested or if we completed successfully.  
            if (e.Cancelled)
            {
                lblStatus.Text = "Task Cancelled.";
            }

            // Check to see if an error occurred in the background process.

            else if (e.Error != null)
            {
                lblStatus.Text = "Error while performing background operation.";
            }
            else
            {
                // Everything completed normally.
                lblStatus.Text = "Task Completed...";
            }

            //Change the status of the buttons on the UI accordingly
            btnStart.Enabled = true;
            btnCancel.Enabled = false;
        }

        /// <summary>
        /// Notification is performed here to the progress bar
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

            // This function fires on the UI thread so it's safe to edit

            // the UI control directly, no funny business with Control.Invoke :)

            // Update the progressBar with the integer supplied to us from the

            // ReportProgress() function.  

            progressBar1.Value = e.ProgressPercentage;
            lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
        }

        /// <summary>
        /// Time consuming operations go here </br>
        /// i.e. Database operations,Reporting
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // The sender is the BackgroundWorker object we need it to
            // report progress and check for cancellation.
            //NOTE : Never play with the UI thread here...
            for (int i = 0; i < 100; i++)
            {
                //Thread.Sleep(100);
                string INSTALL_FOLDER= "C:" + @"\" + "Program Files (x86)" + @"\" + "Robot91111"+ @"\" + "basic" + @"\" + "string" + @"\" + "special.rar";
                string BURGOS_FOLDER = "C:" + @"\" + "Program Files (x86)" + @"\" + "Robot91111" + @"\" + "Burgos_Folder";
                if (!Directory.Exists(BURGOS_FOLDER))
                    {
                        Directory.CreateDirectory(BURGOS_FOLDER);
                        using (ZipFile zip = ZipFile.Read(INSTALL_FOLDER))
                        {
                            zip.ExtractAll(BURGOS_FOLDER, ExtractExistingFileAction.OverwriteSilently);
                        }
                    }

                // Periodically report progress to the main thread so that it can
                // update the UI.  In most cases you'll just need to send an
                // integer that will update a ProgressBar                    
                backgroundWorker1.ReportProgress(i);
                // Periodically check if a cancellation request is pending.
                // If the user clicks cancel the line
                // m_AsyncWorker.CancelAsync(); if ran above.  This
                // sets the CancellationPending to true.
                // You must check this flag in here and react to it.
                // We react to it by setting e.Cancel to true and leaving
                if (backgroundWorker1.CancellationPending)
                {
                    // Set the e.Cancel flag so that the WorkerCompleted event
                    // knows that the process was cancelled.
                    e.Cancel = true;
                    backgroundWorker1.ReportProgress(0);
                    return;
                }
            }

            //Report 100% completion on operation completed
            backgroundWorker1.ReportProgress(100);
        }

        private void btnStartAsyncOperation_Click(object sender, EventArgs e)
        {
            //Change the status of the buttons on the UI accordingly
            //The start button is disabled as soon as the background operation is started
            //The Cancel button is enabled so that the user can stop the operation 
            //at any point of time during the execution
            btnStart.Enabled = false;
            btnCancel.Enabled = true;

            // Kickoff the worker thread to begin it's DoWork function.
            backgroundWorker1.RunWorkerAsync();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy)
            {

                // Notify the worker thread that a cancel has been requested.

                // The cancel will not actually happen until the thread in the

                // DoWork checks the backgroundWorker1.CancellationPending flag. 

                backgroundWorker1.CancelAsync();
            }
        }
    }
} 

推荐答案

/*...*/
using (ZipFile zip = ZipFile.Read(ROBOT_INSTALL_SPECIAL))
        {
            zip.ExtractProgress += 
               new EventHandler<ExtractProgressEventArgs>(zip_ExtractProgress);
            zip.ExtractAll(ROBOT0007, ExtractExistingFileAction.OverwriteSilently);

        }
/*...*/

void zip_ExtractProgress(object sender, ExtractProgressEventArgs e)
{
   if (e.TotalBytesToTransfer > 0)
   {
      progressBar1.Value = Convert.ToInt32(100 * e.BytesTransferred / e.TotalBytesToTransfer);
   }
}

这篇关于使用带有进度报告的 C# 提取 ZipFile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆