Copy file with progress

3
How do I use the function in C # File.Copy(string path); to copy a file by incrementing a value in a ProgressBar ?

    
asked by anonymous 28.06.2014 / 03:33

3 answers

2

This function can not be used to show progress (it basically calls the native function - Win32 API - CopyFile of kernel32.dll). There is no function in the File class that makes the copy with progress notification, but you can create a wrapper (using PInvoke) on the CopyFileEx native function of the same library, as described here: link .

The answer to a similar question in English OS has a complete implementation of the wrapper.

    
28.06.2014 / 12:29
2

I found a simpler implementation on the OS in the Anton Semenov answer .

public delegate void ProgressChangeDelegate(double percentage, ref bool cancel);
public delegate void CompleteDelegate();

class CustomFileCopier {
    public CustomFileCopier(string source, string dest) {
        this.SourceFilePath = source;
        this.DestFilePath = dest;
        OnProgressChanged += delegate { }; //só para facilitar o exemplo aqui
        OnComplete +=  delegate { }; //só para facilitar o exemplo aqui
    }

    public void Copy() {
        byte[] buffer = new byte[1024 * 1024]; // 1MB buffer
        bool cancelFlag = false;
        using (FileStream source = new FileStream(SourceFilePath, FileMode.Open, FileAccess.Read)) {
            long fileLength = source.Length;
            using (FileStream dest = new FileStream(DestFilePath, FileMode.CreateNew, FileAccess.Write)) {
                long totalBytes = 0;
                int currentBlockSize = 0;
                while ((currentBlockSize = source.Read(buffer, 0, buffer.Length)) > 0) {
                    totalBytes += currentBlockSize;
                    double percentage = (double)totalBytes * 100.0 / fileLength;
                    dest.Write(buffer, 0, currentBlockSize);
                    cancelFlag = false;
                    OnProgressChanged(percentage, ref cancelFlag);
                    if (cancelFlag == true) {break; } // Delete dest file here
                }
            }
        }
        OnComplete();
    }

    public string SourceFilePath { get; set; }
    public string DestFilePath { get; set; }

    public event ProgressChangeDelegate OnProgressChanged;
    public event CompleteDelegate OnComplete;
}

I placed it on GitHub for future reference.

You can make it more complete.

You'll have to do the event signature implementation, something like:

(percentage, cancelFlag) => { if (OnProgressChanged != null)
                                  OnProgressChanged(percentage, ref cancelFlag); };

and

(percentage, cancelFlag) => { if (OnComplete != null)
                                   OnComplete(percentage, ref cancelFlag); };

You need to run into another thread and sign the OnProgressChanged event to receive the copy progress notifications.

If you are using WinForms and you want a progress bar ready .Net has one. I do not know if it would be compatible with the class above. I did not have time to test but I do not see why not. You would run PerformStep() within the method that signs the OnProgressChanged event.

Some other options (not to say that I think they are good or bad):

28.08.2014 / 19:24
1

Adds reference to the library: Microsoft.VisualBasic.dll

  

(The DLL can be found in the   C: \ Windows \ Microsoft.NET \ Framework \ version.net.xxx) Choose the .NET version   according to your project

In the code:

using Microsoft.VisualBasic.FileIO;

...
{
   FileSystem.CopyFile(ArqOrigem, ArqDestino, UIOption.AllDialogs);
}
...

  

Source:   link

    
28.12.2015 / 19:54