简体   繁体   English

带进度条的文件复制不起作用

[英]File copy with progress bar not working

I am creating an app in which I use a OpenFileDialog to select a file, put the name into a textbox, and then I would then I open a SaveFileDialog to select a different location (as well as a different filename, if necessary). 我正在创建一个应用程序,在其中使用OpenFileDialog选择文件,将名称放入文本框,然后打开SaveFileDialog选择其他位置(如有必要,还选择其他文件名)。 When I click the button to copy the file, I am using System.IO.File.Copy(<input file name>,<output file name>,<overwrite true/false>) with a progress bar. 当我单击按钮以复制文件时,我正在使用带有进度条的System.IO.File.Copy(<input file name>,<output file name>,<overwrite true/false>) Even when I run the copy on a separate thread, the file is copied instantaneously (even to a network location) and the app freezes while copying. 即使在单独的线程上运行副本,文件也会被即时复制(甚至复制到网络位置),并且在复制时应用程序会冻结。 Additionally, the progress bar never moves. 此外,进度栏永远不会移动。 Others have answered similar questions, but I don't know enough about C# to know how to make those answers apply to my code, and I don't know what I am doing wrong. 其他人也回答了类似的问题,但是我对C#的了解不足,不知道如何使这些答案适用于我的代码,而且我也不知道我做错了什么。 My code is below (I put the entire code from the main form to make it easier to understand the flow): 我的代码如下(我将整个代码都放在了主窗体中,以便于理解流程):

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;
        }
    }
}

Firstly, the way you determine the file size/length is incorrect, for you are using the length of characters of the filename itself. 首先,确定文件大小/长度的方法不正确,因为您正在使用文件名本身的字符长度。 To get the file size use: 要获取文件大小,请使用:

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

Secondly, the File.Copy will copy the file in one go, which means you cannot loop around the copy trying to display a progess bar the way you currently doing it. 其次,File.Copy将一次性复制文件,这意味着您无法在复制周围循环尝试以当前方式显示进度条。

To display progress you will have to make use of reading the source file and writing to target file (doing the copy yourself) making use of a FileStream. 要显示进度,您将不得不利用FileStream读取源文件并写入目标文件(自己进行复制)。

That way you can write blocks of bytes out and work out the progress while doing so. 这样,您可以写出字节块并在执行过程中确定进度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM