根据this article,减速的主要原因是由文件副本使用缓冲。
在Windows Vista或更高版本中,可以通过指定COPY_FILE_NO_BUFFERING
指定CopyFileEx()
Windows API function来避免使用缓冲。
可以指定的P/Invoke如下:
enum CopyProgressResult: uint
{
PROGRESS_CONTINUE = 0,
PROGRESS_CANCEL = 1,
PROGRESS_STOP = 2,
PROGRESS_QUIET = 3
}
enum CopyProgressCallbackReason: uint
{
CALLBACK_CHUNK_FINISHED = 0x00000000,
CALLBACK_STREAM_SWITCH = 0x00000001
}
delegate CopyProgressResult CopyProgressRoutine(
long TotalFileSize,
long TotalBytesTransferred,
long StreamSize,
long StreamBytesTransferred,
uint dwStreamNumber,
CopyProgressCallbackReason dwCallbackReason,
IntPtr hSourceFile,
IntPtr hDestinationFile,
IntPtr lpData);
[Flags]
enum CopyFileFlags: uint
{
COPY_FILE_FAIL_IF_EXISTS = 0x00000001,
COPY_FILE_RESTARTABLE = 0x00000002,
COPY_FILE_OPEN_SOURCE_FOR_WRITE = 0x00000004,
COPY_FILE_ALLOW_DECRYPTED_DESTINATION = 0x00000008,
COPY_FILE_COPY_SYMLINK = 0x00000800, //NT 6.0+
COPY_FILE_NO_BUFFERING = 0x00001000
}
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CopyFileEx
(
string lpExistingFileName,
string lpNewFileName,
CopyProgressRoutine lpProgressRoutine,
IntPtr lpData,
ref Int32 pbCancel,
CopyFileFlags dwCopyFlags
);
然后调用它(替换为您自己的文件名);
int cancel = 0;
CopyFileEx(@"C:\tmp\test.bin", @"F:\test.bin", null, IntPtr.Zero, ref cancel, CopyFileFlags.COPY_FILE_NO_BUFFERING);
这可能值得尝试一下,看看它是否有帮助。
如何复制文件?如果你只是在做一堆连续的文件副本,听起来就像你的服务器只是不足够的。如果你想要并行运行多个副本,那么你应该把你的代码构造成不那么激进。 – 2014-09-24 11:47:33
我正在复制基于数据库查询的特定文件。不是平行复制,它一次复制1个文件。 – oshirowanen 2014-09-24 11:48:06
这不能回答我的问题。你能显示一些代码吗? – 2014-09-24 11:48:36