c# - 复制大文件时更新进度条

标签 c# .net visual-studio-2010

我正在寻找一种在将文件从一个位置复制到另一个位置时更新进度条的方法。

我正在 BackgroundWorker 中进行复制,并且进度条也在后台更新。我尝试过使用 file.length 来获取文件大小,并使用它来计算百分比并以这种方式更新栏,但没有任何乐趣。

我正在附上代码,如果有任何帮助,我们将不胜感激,谢谢。

namespace Copier

{ 公共(public)部分类 Form1 :表格 { 公共(public)表格1() { 初始化组件(); }

    // Declare for use in all methods
    public string copyFrom;
    public string copyTo;

    private void btnCopyFrom_Click(object sender, EventArgs e)
    {
        // uses a openFileDialog, openFD, to chose the file to copy
        copyFrom = "";

        openFD.InitialDirectory = @"C:\Documents and Settings\user\My Documents";
        openFD.FileName = "";

        //openFD.ShowDialog();

        if (openFD.ShowDialog() == DialogResult.Cancel)
        {
            MessageBox.Show("cancel button clicked");
        }

        else
        {
            // sets copyFrom = to the file chosen from the openFD
            copyFrom = openFD.FileName;
            // shows it in a textbox
            txtCopyFrom.Text = copyFrom;
        }
    }

    private void btnCopyTo_Click(object sender, EventArgs e)
    {
        //uses folderBrowserDialog, folderBD, to chose the folder to copy to
        copyTo = "";

        this.folderBD.RootFolder = System.Environment.SpecialFolder.MyComputer;
        this.folderBD.ShowNewFolderButton = false;
        //folderBD.ShowDialog();
        //DialogResult result = this.folderBD.ShowDialog();

        if (folderBD.ShowDialog() == DialogResult.Cancel)
        {
            MessageBox.Show("cancel button clicked");
        }
        else
        {
            // sets copyTo = to the folder chosen from folderBD
            copyTo = this.folderBD.SelectedPath;
            //shows it in a textbox.
            txtCopyTo.Text = copyTo;
        }
    }

    private void btnCopy_Click(object sender, EventArgs e)
    {
        copyBGW.RunWorkerAsync();
    }

    private void btnCancel_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }

    //=================================================================
    //                      BackGroundWorkers
    //=================================================================

    private void copyBGW_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            // copies file
            string destinatationPath = Path.Combine(copyTo, Path.GetFileName(copyFrom));
            File.Copy(copyFrom, destinatationPath);
            MessageBox.Show("File Copied");
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}

或者有人可以告诉我一种方法,让进度条自行移动,这样它就表明表单没有卡住?

已经清理了代码

感谢您迄今为止的投入

最佳答案

我认为最简单的方法是调用 CopyFileEx,它允许您指定进度处理程序,以便在复制文件时从操作系统获取更新。以下是从 pinvoke.net 页面复制的示例代码 CopyFileEx :

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CopyFileEx(string lpExistingFileName, string lpNewFileName,
   CopyProgressRoutine lpProgressRoutine, IntPtr lpData, ref Int32 pbCancel,
   CopyFileFlags dwCopyFlags);

delegate CopyProgressResult CopyProgressRoutine(
long TotalFileSize,
long TotalBytesTransferred,
long StreamSize,
long StreamBytesTransferred,
uint dwStreamNumber,
CopyProgressCallbackReason dwCallbackReason,
IntPtr hSourceFile,
IntPtr hDestinationFile,
IntPtr lpData);

int pbCancel;

enum CopyProgressResult : uint
{
    PROGRESS_CONTINUE = 0,
    PROGRESS_CANCEL = 1,
    PROGRESS_STOP = 2,
    PROGRESS_QUIET = 3
}

enum CopyProgressCallbackReason : uint
{
    CALLBACK_CHUNK_FINISHED = 0x00000000,
    CALLBACK_STREAM_SWITCH = 0x00000001
}

[Flags]
enum CopyFileFlags : uint
{
    COPY_FILE_FAIL_IF_EXISTS = 0x00000001,
    COPY_FILE_RESTARTABLE = 0x00000002,
    COPY_FILE_OPEN_SOURCE_FOR_WRITE = 0x00000004,
    COPY_FILE_ALLOW_DECRYPTED_DESTINATION = 0x00000008
}

private void XCopy(string oldFile, string newFile)
{
    CopyFileEx(oldFile, newFile, new CopyProgressRoutine(this.CopyProgressHandler), IntPtr.Zero, ref pbCancel, CopyFileFlags.COPY_FILE_RESTARTABLE);
}

private CopyProgressResult CopyProgressHandler(long total, long transferred, long streamSize, long StreamByteTrans, uint dwStreamNumber,CopyProgressCallbackReason reason, IntPtr hSourceFile, IntPtr hDestinationFile, IntPtr lpData)
{
    return CopyProgressResult.PROGRESS_CONTINUE;
}

关于c# - 复制大文件时更新进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10517869/

相关文章:

windows - 在没有程序集 list 的情况下在 GAC 中注册 DLL

c# - 将 lambda 用于 winforms 事件有什么问题吗?

c# - 如何将文本框设置为仅允许数字、一 (1) 个逗号和破折号(用于负数)开头

.net - 在没有 Access 权限的情况下打开 mdb Access 文件

.net - 为项目设置默认构建配置

c++ - 在实例方法中使用 find_if

c# - SQL数据源参数

mixed-mode - 混合模式库和 CRT 依赖项 - 帮助

c# - 使用 .NET SslStream 的 FTPS 服务器

c# - XmlSerializer.Deserialize 是否将整个文档加载到内存中?