Dear Sirs!

Faced such a problem: Copying the SourceFile file to DestFile using

 File.Copy(SourceFile, DestFile, true); 

The copying itself is excellent, but further work with the File SourceFile file FileStream occurs with a noticeable slowdown! After 20 seconds, if you do not use this file, work becomes fast again.

Both the SourceFile and DestFile are in the same network folder. The essence of the task is that I need to make a backup of it in the same folder before some operations on the file. There is no problem when the folder is local, but when networked, this problem arises.

Maybe something with file system caching over the network?

When I use the manual read-write method for file streams for copying, there are certainly no problems with slowing down, but the truth is that copying itself (backup) takes longer. For this, I wanted to use File.Copy in order not to generate traffic on the network ...

I would be happy to help! Thanks in advance.

  • Manual copying is slower even for the delay after applying File.Copy. Everything is logical, nothing is given for nothing, especially when working with a network. Well, yes, of course, the WinAPI source code certainly didn’t climb, but I think a buffer is used for network copying in order to free the source file as soon as possible, since data transfer over the network can be long - rdorn
  • In general, I thought so, but ... File.Copy is a kind of synchronous function. Accordingly, in theory, I can count on the fact that after its implementation, all the resources she needs are released. And then, I hoped that there was no need to really copy something, but it was enough just to send a command to the remote computer (after all, both files are on the same remote computer), wait for the execution and return control to me. If all this is not so, then sadness. It's good that the new FileStream.CopyTo works noticeably better than the old manual approach ... - Boris

1 answer 1

Function code File.Copy:

 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"); File.InternalCopy(sourceFileName, destFileName, false, true); } 

from where it is called:

 internal static string InternalCopy(string sourceFileName, string destFileName, bool overwrite, bool checkHost) { string fullPathInternal1 = Path.GetFullPathInternal(sourceFileName); string fullPathInternal2 = Path.GetFullPathInternal(destFileName); FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPathInternal1, false, false); FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullPathInternal2, false, false); if (!Win32Native.CopyFile(fullPathInternal1, fullPathInternal2, !overwrite)) { int lastWin32Error = Marshal.GetLastWin32Error(); string maybeFullPath = destFileName; if (lastWin32Error != 80) { using (SafeFileHandle file = Win32Native.UnsafeCreateFile(fullPathInternal1, int.MinValue, FileShare.Read, (Win32Native.SECURITY_ATTRIBUTES) null, FileMode.Open, 0, IntPtr.Zero)) { if (file.IsInvalid) maybeFullPath = sourceFileName; } if (lastWin32Error == 5 && Directory.InternalExists(fullPathInternal2)) throw new IOException(Environment.GetResourceString("Arg_FileIsDirectory_Name", (object) destFileName), 5, fullPathInternal2); } __Error.WinIOError(lastWin32Error, maybeFullPath); } return fullPathInternal2; } 

As you can see, the Win32 function CopyFile is used, in connection with this, when the File.Copy function has already finished its work, the file could in fact not be copied by the operating system. When you directly copy through streams, this does not happen, apparently, copying occurs immediately. I hope someone will explain in more detail.

  • And where did you find this code? - Philippe
  • Using the dotPeek decompiler in the C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ mscorlib.dll assembly. Net Framework v4.6.1 - konoplinovich
  • Here, for example, System.IO.FileStream.Read: pastebin.com/yi1AeFkU - immediately visible, the function is busy. - konoplinovich
  • @Philippe you can see the same code in the open source referencesource.microsoft.com/#mscorlib/system/io/… - rdorn