File.Copy vs. Manual FileStream.Write For Copying File
File.Copy was build around CopyFile Win32 function and this function takes lot of attention from MS crew (remember this Vista-related threads about slow copy performance).
Several clues to improve performance of your method:
- Like many said earlier remove Flush method from your cycle. You do not need it at all.
- Increasing buffer may help, but only on file-to-file operations, for network shares, or ftp servers this will slow down instead. 60 * 1024 is ideal for network shares, at least before vista. for ftp 32k will be enough in most cases.
- Help os by providing your caching strategy (in your case sequential reading and writing), use FileStream constructor override with FileOptions parameter (SequentalScan).
- You can speed up copying by using asynchronous pattern (especially useful for network-to-file cases), but do not use threads for this, instead use overlapped io (BeginRead, EndRead, BeginWrite, EndWrite in .net), and do not forget set Asynchronous option in FileStream constructor (see FileOptions)
Example of asynchronous copy pattern:
int Readed = 0;
IAsyncResult ReadResult;
IAsyncResult WriteResult;
ReadResult = sourceStream.BeginRead(ActiveBuffer, 0, ActiveBuffer.Length, null, null);
do
{
Readed = sourceStream.EndRead(ReadResult);
WriteResult = destStream.BeginWrite(ActiveBuffer, 0, Readed, null, null);
WriteBuffer = ActiveBuffer;
if (Readed > 0)
{
ReadResult = sourceStream.BeginRead(BackBuffer, 0, BackBuffer.Length, null, null);
BackBuffer = Interlocked.Exchange(ref ActiveBuffer, BackBuffer);
}
destStream.EndWrite(WriteResult);
}
while (Readed > 0);
Are there any difference in using File.Copy to move a file or to write a stream to the location?
File.Copy
simply encapsulates the usage of streams, etc. No difference at all.
File.Copy versus read and write in C#
As you can see with Reflector, File.Copy use native windows methods to create a duplicate. I think it will be faster that read bytes from one stream and write to another one.
public static void Copy(string sourceFileName, string destFileName)
{
if (sourceFileName == null)
{
throw new ArgumentNullException("sourceFileName", Environment.GetResourceString("ArgumentNull_FileName"));
}
if (destFileName == null)
{
throw new ArgumentNullException("destFileName", Environment.GetResourceString("ArgumentNull_FileName"));
}
if (sourceFileName.Length == 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceFileName");
}
if (destFileName.Length == 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
}
InternalCopy(sourceFileName, destFileName, false, true);
}
And content of InternalCopy method is:
[SecuritySafeCritical]
internal static string InternalCopy(string sourceFileName, string destFileName, bool overwrite, bool checkHost)
{
string fullPathInternal = Path.GetFullPathInternal(sourceFileName);
string dst = Path.GetFullPathInternal(destFileName);
new FileIOPermission(FileIOPermissionAccess.Read, new string[] { fullPathInternal }, false, false).Demand();
new FileIOPermission(FileIOPermissionAccess.Write, new string[] { dst }, false, false).Demand();
if (!Win32Native.CopyFile(fullPathInternal, dst, !overwrite))
{
int errorCode = Marshal.GetLastWin32Error();
string maybeFullPath = destFileName;
if (errorCode != 80)
{
using (SafeFileHandle handle = Win32Native.UnsafeCreateFile(fullPathInternal, -2147483648, FileShare.Read, null, FileMode.Open, 0, IntPtr.Zero))
{
if (handle.IsInvalid)
{
maybeFullPath = sourceFileName;
}
}
if ((errorCode == 5) && Directory.InternalExists(dst))
{
throw new IOException(Environment.GetResourceString("Arg_FileIsDirectory_Name", new object[] { destFileName }), 5, dst);
}
}
__Error.WinIOError(errorCode, maybeFullPath);
}
return dst;
}
How to use filestream for copying files in c#
for copying i used below code :-
public static void Copy(string inputFilePath, string outputFilePath)
{
int bufferSize = 1024 * 1024;
using (FileStream fileStream = new FileStream(outputFilePath, FileMode.OpenOrCreate, FileAccess.Write,FileShare.ReadWrite))
//using (FileStream fs = File.Open(<file-path>, FileMode.Open, FileAccess.Read, FileShare.Read))
{
FileStream fs = new FileStream(inputFilePath, FileMode.Open, FileAccess.ReadWrite);
fileStream.SetLength(fs.Length);
int bytesRead = -1;
byte[] bytes = new byte[bufferSize];
while ((bytesRead = fs.Read(bytes, 0, bufferSize)) > 0)
{
fileStream.Write(bytes, 0, bytesRead);
}
}
}
Performance wise: File.Copy vs File.WriteAllText function in C#?
If the file is relatively small it is likely to remain cached in Windows disk cache, so the performance difference will be small, or it might even be that File.Copy()
is faster (since Windows will know that the data is the same, and File.Copy()
calls a Windows API that is extremely optimised).
If you really care, you should instrument it and time things, although the timings are likely to be completely skewed because of Windows file caching.
One thing that might be important to you though: If you use File.Copy()
the file attributes including Creation Time will be copied. If you programatically create all the files, the Creation Time is likely to be different between the files.
If this is important to you, you might want to programatically set the the file attributes after the copy so that they are the same for all files.
Personally, I'd use File.Copy()
.
Is C# File.Copy close to the same thing as copying a file via explorer in terms of performance?
As you can see in the reference source, the File.Copy
method internally uses a native Win32 call, specifically CopyFile
(from here in the reference source).
The performance should be more or less the same as Windows Explorer. There is just a little overhead, but that wouldn't do anything in the actual copying.
File.Copy a file created in memory
Use File.WriteAllBytes to create a new file (or overwrite an existing file) from a byte array:
File.WriteAllBytes(fileName, bytes);
Note that a MemoryStream (what you created) really isn't a "file", so File.Copy
can't be used.
Related Topics
Filter SQL Based on C# List Instead of a Filter Table
How to Remove New Line Characters from a String
Units of Measure in C# - Almost
Single Click Edit in Wpf Datagrid
Advantages to Using Private Static Methods
Get Text/Value from Textbox After Value/Text Changed Server Side
Newtonsoft JSON.Net Deserialization Error Where Fields in JSON Change Order
What Does System.Double[*] Mean
How to Deserialize Xml If the Return Type Could Be an Error or Success Object
Getting Hash of a List of Strings Regardless of Order