[英]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.