簡體   English   中英

帶進度條的文件復制不起作用

[英]File copy with progress bar not working

我正在創建一個應用程序,在其中使用OpenFileDialog選擇文件,將名稱放入文本框,然后打開SaveFileDialog選擇其他位置(如有必要,還選擇其他文件名)。 當我單擊按鈕以復制文件時,我正在使用帶有進度條的System.IO.File.Copy(<input file name>,<output file name>,<overwrite true/false>) 即使在單獨的線程上運行副本,文件也會被即時復制(甚至復制到網絡位置),並且在復制時應用程序會凍結。 此外,進度欄永遠不會移動。 其他人也回答了類似的問題,但是我對C#的了解不足,不知道如何使這些答案適用於我的代碼,而且我也不知道我做錯了什么。 我的代碼如下(我將整個代碼都放在了主窗體中,以便於理解流程):

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

namespace FileProgress
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        // Declare variables here.
        OpenFileDialog ofd = new OpenFileDialog();
        SaveFileDialog sfd = new SaveFileDialog();
        FolderBrowserDialog fbd = new FolderBrowserDialog();
        BackgroundWorker bgWorker = new BackgroundWorker();
        string strInputFile;
        string strOutputFile;
        int intInputFileSize;
        int intOutputFileSize;
        int intFileProgress;


        private void Form1_Load(object sender, EventArgs e)
        {
            // Set up the form with defaults.
            txtInputFile.Text = "Please select a file.";
            txtInputFile.ForeColor = Color.Gray;
            txtOutputFile.Text = "Please select the location you want to copy the file to.";
            txtOutputFile.ForeColor = Color.Gray;

        }

        private void txtInputFile_MouseClick(object sender, MouseEventArgs e)
        {
            // This will blank out the txtInputFile textbox when clicked.
            if (txtInputFile.Text == "Please select a file.")
            {
                txtInputFile.Text = "";
            }
            // This will put text into the txtOutputFile textbox, if it is blank.
            if (txtOutputFile.Text == "")
            {
                txtOutputFile.Text = "Please select the location you want to copy the file to.";
            }
        }

        private void txtOutputFile_MouseClick(object sender, MouseEventArgs e)
        {
            // This will blank out the txtOutputFile textbox when clicked.
            if (txtOutputFile.Text == "Please select the location you want to copy the file to.")
            {
                txtOutputFile.Text = "";
            }
            // This will put text into the txtInputFile textbox, if it is blank.
            if (txtInputFile.Text == "")
            {
                txtInputFile.Text = "Please select a file.";
            }
        }

        private void btnInputFile_Click(object sender, EventArgs e)
        {
            // Here we open the OpenFileDialog (ofd) and select the file we want to copy.
            // Change the text color in the textbox to black.
            txtInputFile.ForeColor = Color.Black;
            ofd.FileName = String.Empty;
            // Set the initial directory.
            ofd.InitialDirectory = "%HOMEPATH%";
            ofd.Title = "Select a file";
            // We want to be able to open any type of file.
            ofd.Filter = "All files (*.*)|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                // Set the filename as the text of the textbox txtInputFile.
                strInputFile = ofd.FileName;
                txtInputFile.Text = strInputFile;
                // Get the length of the file. 
                //This seems to be getting the number of characters in the path and filename.
                intInputFileSize = strInputFile.Length;
                // Enable the Copy button.
                btnCopy.Enabled = true;
            }
        }

        private void btnOutputFile_Click(object sender, EventArgs e)
        {
            // Here we open the SaveFileDialog (sfd) and select the location where we want to copy the file to.
            // Change the text color in the textbox to black.
            txtOutputFile.ForeColor = Color.Black;
            sfd.FileName = txtInputFile.Text;
            //We want to see all files
            sfd.Filter = "All files (*.*)|*.*";
            sfd.FilterIndex = 2;
            sfd.RestoreDirectory = true;
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                // Set the text of the txtOutputFile textbox.
                txtOutputFile.Text = sfd.FileName;
                strOutputFile = sfd.FileName;
                // Get the size of the file for debugging purposes.
                //This seems to be getting the number of characters in the path and filename.
                intOutputFileSize = strOutputFile.Length;
            }
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            // We call the background worker to do work on a separate thread.
            bgWorker.RunWorkerAsync();
            // Initialize the the DoWork Event Handler.
            bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
        }

        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // We need to convert the file's size to a percentage.
            intFileProgress = intInputFileSize / 100;
            // Increment the progress bar for each percentage of the file that is copied.
            for (int i = 0; i < (intFileProgress); i++)
            {
                // Actually copy the file.
                File.Copy(strInputFile, strOutputFile, true);
                // Tell the system that the background worker will be reporting progress, and then, actually report the progress.
                bgWorker.WorkerReportsProgress = true;
                bgWorker.ReportProgress(intFileProgress);
            }
        }

        private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // We will increase the progress bar when work progress is reported.
            pbCopyProgress.Value = e.ProgressPercentage;
            pbCopyProgress.Text = (e.ProgressPercentage.ToString() + "%");
        }

        private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // Disable the Copy button once the file has been copied. The messagebox is for debugging only.
            MessageBox.Show("The file " + strOutputFile + " (" + Convert.ToString(intOutputFileSize) + ") has been copied", "Message");
            btnCopy.Enabled = false;
        }
    }
}

首先,確定文件大小/長度的方法不正確,因為您正在使用文件名本身的字符長度。 要獲取文件大小,請使用:

FileInfo fileInfo = new FileInfo(sfd.FileName);
intOutputFileSize = fileInfo.Length;

其次,File.Copy將一次性復制文件,這意味着您無法在復制周圍循環嘗試以當前方式顯示進度條。

要顯示進度,您將不得不利用FileStream讀取源文件並寫入目標文件(自己進行復制)。

這樣,您可以寫出字節塊並在執行過程中確定進度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM