c#Progressbar,溢出返回负值

时间:2017-03-03 08:28:19

标签: c# overflow int32

我正在创建一个备份应用程序。我在不同位置有5个文件夹需要复制到一个备份文件夹。 (通过checkbox.checked解决) 主要问题是一些文件夹总共超过3-4GB(包含所有子文件夹)Progressbar未更新,因为“maxbyte”返回负值。 (我假设在2gb文件复制后int32溢出) (抱歉无法详细解释。我只是一名初学C#程序员)

using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using memoQClientBackuTool;

namespace memoQBackupTool
{
    public partial class BGWorker : Form
    {
        public BGWorker()
        {
            InitializeComponent();
        }

        BackgroundWorker bw;
        string source = "";
        string target = "";
        bool isfile = false;
        int filecount = 0;
        int currentFileNr = 1;
        string newFilename = "";
        int maxbytes = 0;

        public void ShowProgress(string from, string to, bool isf)
        {
            InitializeComponent();

            source = from;
            target = to;
            isfile = isf;

            bw = new BackgroundWorker();
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
            bw.WorkerReportsProgress = true;
            bw.WorkerSupportsCancellation = true;
            GetFileData();
        }

        private void GetFileData()
        {
            if (isfile)
            {
                FileInfo fi = new FileInfo(source);
                maxbytes = Convert.ToInt32(fi.Length);
                //
                //set progress bar length
                //
                progressBar1.Minimum = 0;
                progressBar2.Minimum = 0;
                progressBar1.Maximum = maxbytes;
                progressBar2.Maximum = 1;

                bw.RunWorkerAsync();
            }
            else
            {
                GetDirectoryInfo(source);
                //
                //set progress bar length
                //
                progressBar1.Minimum = 0;
                progressBar2.Minimum = 0;
                progressBar1.Maximum = maxbytes;
                progressBar2.Maximum = filecount;

                bw.RunWorkerAsync();
            }
        }

        private void GetDirectoryInfo(string source)
        {
            string[] files = Directory.GetFiles(source);
            foreach (string file in files)
            {
                FileInfo fi = new FileInfo(file);
                maxbytes += Convert.ToInt32(fi.Length);

                filecount += 1;
            }
            string[] folders = Directory.GetDirectories(source);
            foreach (string folder in folders)
            {
                GetDirectoryInfo(folder);
            }
        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            if (isfile)
            {
                FileStream fs = new FileStream(source, FileMode.Open);
                long FileSize = fs.Length;
                FileInfo fi = new FileInfo(source);
                byte[] bBuffer = new byte[(int)FileSize];
                fs.Read(bBuffer, 0, (int)FileSize);
                fs.Close();
                UpdateLabels(fi.FullName);
                newFilename = fi.Name;

                try
                {
                    FileStream fss = new FileStream(target + "\\" + newFilename, FileMode.CreateNew);
                    BinaryWriter biwr = new BinaryWriter(fss);

                    for (int i = 0; i < bBuffer.Length; i += 15000)
                    {
                        if (i + 15000 < bBuffer.Length)
                        {
                            biwr.Write(bBuffer, i, 15000);
                            bw.ReportProgress(15000);
                        }
                        else
                        {
                            biwr.Write(bBuffer, i, bBuffer.Length - i);
                            bw.ReportProgress(bBuffer.Length - i);
                        }
                    }
                    biwr.Close();
                    fss.Close();

                } catch (IOException){

                    MessageBox.Show("Nincs olyan...");
                }
        }
            else
            {
                string[] temp = source.Split('\\');
                target += "\\" + temp[temp.Count() - 1];

                DirectoryInfo s = new DirectoryInfo(source);
                DirectoryInfo t = new DirectoryInfo(target);
                CopyDirectory(s, t);
            }
            if (bw.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
        }

        public void CopyDirectory(DirectoryInfo di_source, DirectoryInfo di_target)
        {
            if (Directory.Exists(di_target.FullName) == false)
            {
                Directory.CreateDirectory(di_target.FullName);
            }
            foreach (FileInfo fi in di_source.GetFiles())
            {
                newFilename = fi.Name;
                FileStream fs = new FileStream(fi.FullName, FileMode.Open);
                long FileSize = fs.Length;
                byte[] bBuffer = new byte[(int)FileSize];
                fs.Read(bBuffer, 0, (int)FileSize);
                fs.Close();

                UpdateLabels(fi.FullName);

                if (File.Exists(di_target.ToString() + "\\" + fi.Name))
                {
                    Random rand = new Random();
                    newFilename = newFilename + "_" + rand.Next(1, 10000);
                }
                FileStream fss = new FileStream(di_target.ToString() + "\\" + newFilename, FileMode.CreateNew);
                BinaryWriter biwr = new BinaryWriter(fss);

                for (int i = 0; i < bBuffer.Length; i += 500000)
                {
                    if (i + 500000 < bBuffer.Length)
                    {
                        biwr.Write(bBuffer, i, 500000);
                        bw.ReportProgress(500000);
                    }
                    else
                    {
                        biwr.Write(bBuffer, i, bBuffer.Length - i);
                        bw.ReportProgress(bBuffer.Length - i);
                    }
                }
                biwr.Close();
                fss.Close();
            }
            foreach (DirectoryInfo di_SourceSubDir in di_source.GetDirectories())
            {
                DirectoryInfo nextSubDir = di_target.CreateSubdirectory(di_SourceSubDir.Name);
                CopyDirectory(di_SourceSubDir, nextSubDir);
            }
        }

        void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value += e.ProgressPercentage;
            int copied = progressBar1.Value / 1024;
            int total = maxbytes / 1024;
            lbl_kbscopied.Text = copied + "/" + total;
        }

        delegate void UpdateLabelsDelegate(string filename);

        void UpdateLabels(string fname)
        {
            if (!InvokeRequired)
            {
                lbl_filename.Text = "Copying: " + fname;
                lbl_filenr.Text = "File: " + currentFileNr + "/" + filecount;
                currentFileNr++;
                progressBar2.Value += 1;
            }
            else
            {
                Invoke(new UpdateLabelsDelegate(UpdateLabels), new object[] { fname });
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            bw.CancelAsync();
        }

        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                Cursor.Current = Cursors.Default;
                CustomMsgBox.Show("The task has been canceled", "Error", "OK");
                this.Close();
            }
            else if (e.Error != null)
            {
                MessageBox.Show("Error. Details: " + (e.Error as Exception).ToString());
            }
            else
            {
                this.Close();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

报告进度不是绝对值,而是相对值;百分比,例如。

假设1MB文件是进度条的100%。这意味着您必须使用100:progressBar1.Maximum = 100对其进行初始化。然后复制的每15000个字节略多于1%。而不是bw.ReportProgress(15000)bw.ReportProgress(1)