提取文件时进度条有问题 [英] Problem with progress bar when extracting files

查看:137
本文介绍了提取文件时进度条有问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我已经完成了一个用于提取文件的Windows应用程序,同时提取显示具有特定提取文件名的进度条。现在我有进度百分比的问题,百分比是计算每个文件(如一个文件提取1 .... 100%,再次为另一个文件提取1 .... 100%)这里现在我想显示进度百分比完全只有1 ---- 100%这个我的进度条也从每个文件提取后的开始跳跃。整个zip文件提取应该显示进度和百分比。



可以帮助我吗?



这是我的代码:





  public   partial   class 进度:表单
{
private BackgroundWorker _zipBGWorker;
私有 委托 void ZipProgressEventHandler (ExtractProgressEventArgs e);
私有 委托 void ExtractEntryProgressEventHandler (ExtractProgressEventArgs e);
private bool AllowClose = false ;

public progress()
{
InitializeComponent();
SetTitle();
}
私有 void SetTitle()
{
this .Text = 提取文件;
}
public string outputpath; public string 路径; public string name;列表与LT;串GT; filenames = new List< string>(); int i = 0 ; string x;
private void progress_Load( object sender,EventArgs e)
{
object [] args = new < span class =code-keyword> object [ 3 ];
args [ 0 ] =路径; args [ 1 ] = outputpath; // 获取路径和另一页的输出路径
_zipBGWorker = new BackgroundWorker();
_zipBGWorker.WorkerSupportsCancellation = true ;
_zipBGWorker.WorkerReportsProgress = false ;
_zipBGWorker.DoWork + = new DoWorkEventHandler(_zipBGWorker_DoWork);
_zipBGWorker.RunWorkerCompleted + = new RunWorkerCompletedEventHandler(_zipBGWorker_RunWorkerCompleted);
_zipBGWorker.RunWorkerAsync(args);
this .Cursor = Cursors.WaitCursor;

label1.Text = + name + To + outputpath;

}
void _zipBGWorker_RunWorkerCompleted( object sender,RunWorkerCompletedEventArgs e)
{
this .Close();
zipfile z = new zipfile();
z.Close();
MessageBox.Show( Extraction Completed);
}

private void _zipBGWorker_DoWork( object sender,DoWorkEventArgs e)
{
object [] args =(对象 [])e.Argument;
var list = args.Cast< string>()。ToList();
string path1 = list [ 0 ];
string op = list [ 1 ];
// UpdateLabel((string)e.Argument);
尝试
{
使用(ZipFile zip = ZipFile.Read(path1))
{
foreach (ZipEntry zfe in zip)
{
string n = zfe.FileName;
filenames.Add(n);
}
SetProgressBarMax(zip.Entries.Count);
zip.ExtractProgress + = new EventHandler< ExtractProgressEventArgs>(zip_ExtractProgress);
zip.ExtractAll(op,ExtractExistingFileAction.OverwriteSilently);
}
}
catch (Exception ex)
{
MessageBox.Show( string .Format( 提取该zip文件时出现问题。{0 },ex.Message),
错误提取,MessageBoxButtons .OK,MessageBoxIcon.Exclamation,MessageBoxDefaultButton.Button1);
}
}
void zip_ExtractProgress( object sender,ExtractProgressEventArgs e )
{
if (e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
{
StepEntryProgress(e);
}
}

私有 void SetProgressBarMax( int n)
{
if (progressBar1.InvokeRequired)
{
progressBar1.Invoke( new 操作< int>(SetProgressBarMax), object [] {n});
}
else
{
progressBar1.Maximum = n;
progressBar1.Step = 1 ;
}
}
int f = 0 ;
private void StepEntryProgress(ExtractProgressEventArgs e)
{

if (progressBar1.InvokeRequired)
{
progressBar1.Invoke( new ExtractEntryProgressEventHandler( this .StepEntryProgress), new object [] {e});

}
else
{
progressBar1.Style = ProgressBarStyle.Marquee;
progressBar1.Maximum = 100 ;
progressBar1.Value = Convert.ToInt32( 100 * e.BytesTransferred / e.TotalBytesToTransfer);
int percent =( int )(( double )(progressBar1.Value - progressBar1.Minimum)/( double )(progressBar1.Maximum - progressBar1.Minimum))* 100 );
updatepercent(percent.ToString());

// DateTime time = DateTime.Now;

// 如果endTime.Subtract(startTime).TotalSeconds> 60然后
// lblFileName.Text =完成。此操作采用& _
// endTime.Subtract(startTime).Minutes.ToString()& _
// 分钟和& endTime.Subtract(startTime).Seconds.ToString()& 秒。
f ++;
if (f> filenames.Count)
{
if (i < filenames.Count)
{
x = filenames [i];
UpdateLabel(x);
int n = filenames.Count - i;
Updatefiles(n.ToString());
i ++;
}
}
}

}
void UpdateLabel( string s)
{
if this .label1.InvokeRequired)
{
// 它位于不同的线程上,因此请使用调用。
.BeginInvoke( new MethodInvoker(()= > UpdateLabel(s)));
}
其他
{
// < span class =code-comment>它在同一个线程上,不需要调用

this .label2.Text = s;
}
}
void Updatefiles( string s)
{
if this .label3.InvokeRequired)
{
// 它位于不同的线程上,因此请使用Invoke。
.BeginInvoke( new MethodInvoker(()= > UpdateLabel(S)));
}
其他
{
// < span class =code-comment>它在同一个线程上,不需要调用

这个 .label3.Text = 剩余项目 + s;
}
}
void updatepercent( string s)
{
if this .label4.InvokeRequired)
{
// 它位于不同的线程上,因此请使用Invoke。
.BeginInvoke( new MethodInvoker(()= > UpdateLabel(S)));
}
其他
{
// < span class =code-comment>它在同一个线程上,不需要调用
这个 .label4.Text = s + < span class =code-string> ;
}
}

public void ForceClose( )
{
AllowClose = true ;
this .Close();
AllowClose = false ;
}

private void progress_FormClosing( object sender,FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing& & AllowClose)
{
e.Cancel = true ;
}
}
}

解决方案

定义一个变量:

  int  lastBytesTransferred =  0 ; 





您可以获得zip文件中所有文件的总大小,然后:

 progressBar1.Maximum =总大小; 
progressBar1.Value + = e.BytesTransferred - lastBytesTransferred;
lastBytesTransferred = e.BytesTransferred;





注意:

当文件是提取集:

 lastBytesTransferred =  0 ; 


你应该使用backgroundworker imo的progresschanged事件,然后你可以进行进度条更新。否则会导致交叉线程异常。


  int  fileCount =  0 ; 
long totalSize = 0 ,total = 0 ,lastVal = 0 ,sum = 0 ;

public void ReadAndExtract( string openPath, string savePath)
{
try
{
fileCount = 0 ;
Ionic.Zip.ZipFile myZip = new Ionic.Zip.ZipFile();
myZip = Ionic.Zip.ZipFile.Read(openPath);
foreach var 条目 myZip)
{
fileCount ++;
totalSize + = entry.UncompressedSize;
}
progressBar1.Maximum =( Int32 )totalSize;
myZip.ExtractProgress + = new EventHandler< ionic.zip.extractprogresseventargs>(myZip_ExtractProgress);
myZip.ExtractAll(savePath,Ionic.Zip.ExtractExistingFileAction.OverwriteSilently);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message) );
}
}

void myZip_ExtractProgress( object sender,Ionic.Zip.ExtractProgressEventArgs e)
{

System.Windows.Forms.Application.DoEvents();
if (total!= e.TotalBytesToTransfer)
{
sum + = total - lastVal + e.BytesTransferred;
total = e.TotalBytesToTransfer;
}
else
sum + = e.BytesTransferred - lastVal;

lastVal = e.BytesTransferred;

progressBar1.Value =( Int32 )sum;
}
< / ionic.zip.extractprogresseventargs >


Hi,

i have done an windows app for extracting files, while extracting am showing the progress bar with particular extracting file name. now i have problem with progress percentage, percentage is calculating for each file(like for one file extraction 1....100% and again for another file extraction 1....100%) here now i want to show the progress percentage totally once only 1----100% with this my progress bar also jumping from starting after every file extraction. Progress and percentage should be show for whole zip file extraction.

can any one help me?

here is my code:


public partial class progress : Form
    {
        private BackgroundWorker _zipBGWorker;
        private delegate void ZipProgressEventHandler(ExtractProgressEventArgs e);
        private delegate void ExtractEntryProgressEventHandler(ExtractProgressEventArgs e);
        private bool AllowClose = false;

        public progress()
        {
            InitializeComponent();
            SetTitle();
        }
        private void SetTitle()
        {
            this.Text = "Extracting Files";
        }
        public string outputpath; public string path; public string name; List<string> filenames = new List<string>(); int i = 0; string x;
        private void progress_Load(object sender, EventArgs e)
        {
            object[] args=new object[3];
            args[0] = path; args[1] = outputpath;//getting path and outputpath from another page
            _zipBGWorker = new BackgroundWorker();
            _zipBGWorker.WorkerSupportsCancellation = true;
            _zipBGWorker.WorkerReportsProgress = false;
            _zipBGWorker.DoWork += new DoWorkEventHandler(_zipBGWorker_DoWork);
            _zipBGWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_zipBGWorker_RunWorkerCompleted);
            _zipBGWorker.RunWorkerAsync(args);
            this.Cursor = Cursors.WaitCursor;

            label1.Text = "Extracting from "+name+" To "+outputpath;

        }
        void _zipBGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Close();
            zipfile z = new zipfile();
            z.Close();
            MessageBox.Show("Extraction Completed");
        }

        private void _zipBGWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] args = (object[])e.Argument;
            var list = args.Cast<string>().ToList();
            string path1 = list[0];
            string op = list[1];
            //UpdateLabel((string)e.Argument);
            try
            {
                using (ZipFile zip = ZipFile.Read(path1))
                {
                    foreach (ZipEntry zfe in zip)
                    {
                        string n = zfe.FileName;
                        filenames.Add(n);
                    }
                    SetProgressBarMax(zip.Entries.Count);
                    zip.ExtractProgress += new EventHandler<ExtractProgressEventArgs>(zip_ExtractProgress);
                    zip.ExtractAll(op, ExtractExistingFileAction.OverwriteSilently);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("There's been a problem extracting that zip file.  {0}", ex.Message),
                       "Error Extracting", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
            }
        }
        void zip_ExtractProgress(object sender, ExtractProgressEventArgs e)
        {
            if (e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
            {
                StepEntryProgress(e);
            }
        }

        private void SetProgressBarMax(int n)
        {
            if (progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new Action<int>(SetProgressBarMax), new object[] { n });
            }
            else
            {
                progressBar1.Maximum = n;
                progressBar1.Step = 1;
            }
        }
        int f = 0;
        private void StepEntryProgress(ExtractProgressEventArgs e)
        {

            if (progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new ExtractEntryProgressEventHandler(this.StepEntryProgress), new object[] { e });

            }
            else
            {
                progressBar1.Style = ProgressBarStyle.Marquee;
                progressBar1.Maximum = 100;
                progressBar1.Value = Convert.ToInt32(100 * e.BytesTransferred / e.TotalBytesToTransfer);
                int percent = (int)(((double)(progressBar1.Value - progressBar1.Minimum) / (double)(progressBar1.Maximum - progressBar1.Minimum)) * 100);
                updatepercent(percent.ToString());

                //DateTime time = DateTime.Now;

                //If endTime.Subtract(startTime).TotalSeconds > 60 then
                //                lblFileName.Text = "Complete. This operation took " & _
                //                    endTime.Subtract(startTime).Minutes.ToString() & _
                //                   " minutes, and " & endTime.Subtract(startTime).Seconds.ToString() & " seconds."
                f++;
                if (f>filenames.Count)
                {
                    if (i < filenames.Count)
                    {
                        x = filenames[i];
                        UpdateLabel(x);
                        int n = filenames.Count - i;
                        Updatefiles(n.ToString());
                        i++;
                    }
                }
            }

        }
        void UpdateLabel(string s)
        {
            if (this.label1.InvokeRequired)
            {
                // It's on a different thread, so use Invoke.
                this.BeginInvoke (new MethodInvoker(() => UpdateLabel(s)));
            }
            else
            {
                // It's on the same thread, no need for Invoke
                this.label2.Text = s;
            }
        }
        void Updatefiles(string s)
        {
            if (this.label3.InvokeRequired)
            {
                // It's on a different thread, so use Invoke.
                this.BeginInvoke(new MethodInvoker(() => UpdateLabel(s)));
            }
            else
            {
                // It's on the same thread, no need for Invoke
                this.label3.Text = "Remaining items "+s;
            }
        }
        void updatepercent(string s)
        {
            if (this.label4.InvokeRequired)
            {
                // It's on a different thread, so use Invoke.
                this.BeginInvoke(new MethodInvoker(() => UpdateLabel(s)));
            }
            else
            {
                // It's on the same thread, no need for Invoke
                this.label4.Text = s +"%";
            }
        }

        public void ForceClose()
        {
            AllowClose = true;
            this.Close();
            AllowClose = false;
        }

        private void progress_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing && AllowClose)
            {
                e.Cancel = true;
            }
        }
    }

解决方案

define an variable:

int lastBytesTransferred =0;



you can get total size of all file`s in zip file and then :

progressBar1.Maximum = total size;
progressBar1.Value += e.BytesTransferred - lastBytesTransferred;
lastBytesTransferred = e.BytesTransferred;



Attention:
when a file was extracted set:

lastBytesTransferred = 0;


You should use progresschanged event of backgroundworker imo, then you can do your progressbar update. Else you cause "Cross Thread" exception.


    int fileCount = 0;
    long totalSize = 0, total = 0, lastVal=0,sum=0;

    public void ReadAndExtract(string openPath, string savePath)
    {
        try
        {
            fileCount = 0;
            Ionic.Zip.ZipFile myZip = new Ionic.Zip.ZipFile();
            myZip = Ionic.Zip.ZipFile.Read(openPath);
            foreach (var entry in myZip)
            {
                fileCount++;
                totalSize += entry.UncompressedSize;
            }
            progressBar1.Maximum = (Int32)totalSize;
            myZip.ExtractProgress += new EventHandler<ionic.zip.extractprogresseventargs>(myZip_ExtractProgress);
            myZip.ExtractAll(savePath,Ionic.Zip.ExtractExistingFileAction.OverwriteSilently);
        }
        catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message);
        }
    }

    void myZip_ExtractProgress(object sender, Ionic.Zip.ExtractProgressEventArgs e)
    {

        System.Windows.Forms.Application.DoEvents();
        if (total != e.TotalBytesToTransfer)
        {
            sum += total - lastVal + e.BytesTransferred;
            total = e.TotalBytesToTransfer;
        }
        else
            sum += e.BytesTransferred - lastVal;

        lastVal = e.BytesTransferred;

        progressBar1.Value = (Int32)sum;
    }
</ionic.zip.extractprogresseventargs>


这篇关于提取文件时进度条有问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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