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
Winforms | C# | Autocomplete in the Middle of a Textbox
Can't Get SQL Server Compact 3.5/4 to Work with Asp .Net MVC 2
Path.Combine Absolute with Relative Path Strings
Why C# Is Not Allowing Non-Member Functions Like C++
How to Execute Process Commands (Or Similar) Using a Universal Windows Platform (Uwp) App
Can't Convert Value Type Array to Params Object[]
Loading a Full Hierarchy from a Self Referencing Table with Entityframework.Core
Force Xmlserializer to Serialize Datetime as 'Yyyy-Mm-Dd Hh:Mm:Ss'
Asynchronous Task.Whenall with Timeout
Programmatically Adding Images to Rtf Document
Azure Ad B2C - Role Management
Handling Executescalar() When No Results Are Returned
Initialization Order of Static Fields in Static Class