How to Show File Copy Progress Using Fileinfo.Copyto() in .Net

Can I show file copy progress using FileInfo.CopyTo() in .NET?

The FileInfo.CopyTo is basically a wrapper around the Win32 API call "CopyFile" in the kernel32.dll. This method does not support progress callback.

However, the CopyFileEx method does, and you can write your own .NET wrapper around it in a few minutes, like it is described here:
http://www.pinvoke.net/default.aspx/kernel32.CopyFileEx

File Copy with Progress Bar

You need something like this:

    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 { };
OnComplete += delegate { };
}

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)
{
// Delete dest file here
break;
}
}
}
}

OnComplete();
}

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

public event ProgressChangeDelegate OnProgressChanged;
public event Completedelegate OnComplete;
}

Just run it in separate thread and subscribe for OnProgressChanged event.

stream.copyto with progress bar reporting

You could read the file in chunks.

You should notify the BackgroundWorker in between.

using (Stream output = File.OpenWrite(dest))
{
foreach (string inputFile in files)
{
using (Stream input = File.OpenRead(inputFile))
{
byte[] buffer = new byte[16 * 1024];

int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);

// report progress back
progress = (count / max + read / buffer.Length /* part of this file */) * 100;
backgroundWorker2.ReportProgress(Convert.ToInt32(progress));
}

count++;
progress = count * 100 / max;
backgroundWorker2.ReportProgress(Convert.ToInt32(progress));
}
}
}

C# working with progress bar while copying a file

You could check the size of the folder you're moving it to and use it as the current value of the progress bar.

Update progress bar while copying a large file

This can't work on multiple levels. First of all, the background worker needs to be set to "report changes" via WorkerReportsProgress, but this flag doesn't mean he can do that automatically, of course that won't work. For that the Worker provides the method ReportProgress you need to call that method to show the current progress. And this reveals the final flaw of your approach. The File.Copy method is blocking but your worker needs time to call the ReportProgress method. So you need to find a way to copy your file asynchronously. This question might help and of course Dave Bishs comment is a very good reference for async file copy.

Copy many files and directories using the system file progress dialog?

If you want to copy files or directories, and have the system provided copy progress dialog, then you are looking for either SHFileOperation or IFileOperation.

If you wish to support XP then you need to use SHFileOperation at least on that platform. At which point you may as well, in my opinion, use SHFileOperation on all platforms. On the other hand, if you are prepared to neglect XP, then you should probably use IFileOperation.

Both are pretty easy to use from C#. For SHFileOperation you can use the p/invoke declarations provided at pinvoke.net. Since this is a very widely used and useful function there is a good chance that the p/invokes provided there are of good quality.

For IFileOperation I'm less familiar with the options. This MSDN article looks to be promising: http://msdn.microsoft.com/en-us/magazine/cc163304.aspx

FileInfo.CopyTo returns ArgumentException:

CopyTo copies the content of one file from another file. However, you are specifying the directory instead of the file name. That is the cause of your exception. Refer here for more details



Related Topics



Leave a reply



Submit