Почему FileStream и CopyFile работают намного медленнее, чем Windows Explorer?

Я пытаюсь скопировать файл по сети (Windows Server 2008 R2 в Windows 7 с пакетом обновления 1), а когда я перетаскиваю его с помощью проводника Windows, я получаю около 4,5 МБ/с. (Это соединение WAN)

Однако, когда я использую FileStream.Read(), я получаю только 1.5 МБ/с. Я пробовал разные размеры буфера от 1 КБ до 4 МБ. Я также пытался использовать CopyFile() и CopyFileEx(), но получаю те же результаты.

Что может происходить здесь и как я могу исправить свой код?

EDIT: Я также пытался использовать TeraCopy (сторонний инструмент), и он также получает только 1,5 МБ/с.

2 ответа

Я не знаю, если вы все еще испытываете эту проблему или нет, но я боролся с этой проблемой в течение нескольких дней, поэтому я решил опубликовать ее. Наконец, я нашел решение, совместимое с программой копирования экземпляров. Я не знаю, работает ли это для FileStream, но я был способен использовать CopyFile или CopyFileEx для получения той же производительности. В моем случае CopyFileEx был лучшим выбором, потому что мне нужен обратный вызов прогресса. После использования Process Monitor для проверки процесса копирования я заметил, что система перезагружала позицию потока (даже несмотря на то, что она не перемещалась) перед каждой отдельной операцией чтения и записи для каждой копии файла объемом 32 тыс. (Следовательно, это была низкая производительность). Ключ в любом случае должен установить разрешения IO для исходных и целевых файлов с помощью FileIOPermission перед началом операции копирования.

Вот соответствующий отрывок из моего кода:

new FileIOPermission(FileIOPermissionAccess.Read, SourcePath).Demand();
new FileIOPermission(FileIOPermissionAccess.Write, DestinationPath).Demand();
if (!NativeCopy.CopyFileEx(SourcePath, DestinationPath,
 new NativeCopy.CopyProgressRoutine(this.CopyProgressHandler), GCHandle.ToIntPtr(hArgs),
 ref pbCancel, flags))
{
 throw new IOException(new System.ComponentModel.Win32Exception().Message);
}

Надеется, что это поможет. Это сводило меня с ума, пытаясь понять, что происходит.


Решением для меня было отключить флаг COPY_FILE_RESTARTABLE для CopyFileEx. Я получил примерно 4-5 раз скорость, когда этот флаг был удален.

См. описание MSDN этого флага здесь.

Прогресс копии отслеживается в целевом файле в случае сбоя копии. Это может значительно замедлить операцию копирования как новый файл может быть сброшен несколько раз во время операции копирования.

licensed under cc by-sa 3.0 with attribution.