根據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