Обновление
Дмитрий Мукалов имеет право.Исполнения, которые вы получаете, расширяя внутренний буфер FileStream
, будут убраны, когда вы выполните Flush
.Я копаю немного глубже и сделал некоторый тест, и кажется, что разница между Stream.CopyTo
и FileStream.Write
заключается в том, что Stream.CopyTo
использует более умный буфер ввода-вывода и повышает производительность, копируя чанк по чанку.В конце CopyTo
используйте Write
под капотом.Оптимальный размер буфера обсуждался здесь .
Оптимальный размер буфера связан с рядом факторов: размером блока файловой системы, размером кэша ЦП и задержкой кэша.Большинство файловых систем сконфигурировано для использования блоков размером 4096 или 8192. Теоретически, если вы конфигурируете размер буфера таким образом, что вы читаете на несколько байтов больше, чем дисковый блок, операции с файловой системой могут быть крайне неэффективными (т.е. если высконфигурировал ваш буфер для чтения 4100 байт за раз, при каждом чтении файловая система требовала 2 чтения блока).Если блоки уже находятся в кеше, вы платите цену RAM -> L3 / L2 задержка кеша.Если вам не повезло, а блоки еще не в кеше, вы также платите цену за задержку диска-> ОЗУ.
Поэтому, чтобы ответить на ваш вопрос, в вашем случае вы используете неоптимизированный буферразмеры при использовании Write
и оптимизированные при использовании CopyTo
или, лучше сказать, Stream
само по себе оптимизирует это для вас.
Как правило, вы также можете принудительно использовать неоптимизированный CopyTo
, расширяя FileStream
внутренний буфер, в этом случае результаты должны быть сравнительно медленными, так как неоптимизированные Write
.
FileStream outfile = new FileStream("outputfile",
FileMode.Create,
FileAccess.ReadWrite,
FileShare.Read,
150000000); //internal buffer will lead to inefficient disk write
file1.CopyTo(outfile);
outfile.Flush(); //don't forget to flush data to disk
Оригинал
Я сделал анализ Write
методовFileStream
и MemoryStream
, и дело в том, что MemoryStream
всегда использует внутренний буфер для копирования данных, и это очень быстро.У FileStream
есть переключатель, если запрошено count >= bufferSize
, что верно в вашем случае, так как вы используете буфер по умолчанию FileStream
, размер буфера по умолчанию равен 4096
.В этом случае FileStream
вообще не использует буфер, кроме собственного Win32Native.WriteFile
.
Хитрость заключается в том, чтобы заставить FileStream
использовать буфер, переопределив размер буфера по умолчанию.Попробуйте это:
// Method 2 : FileStream | 8,471 ms
byte[] output = file1.ToArray();
FileStream outfile = new FileStream("outputfile",
FileMode.Create,
FileAccess.ReadWrite,
FileShare.Read,
output.Length + 1); // important, the size of the buffer
outfile.Write(output, 0, output.Length);
nb Я не говорю, что это оптимальный размер буфера, просто объяснение того, что происходит.Чтобы определить наилучший размер буфера с помощью FileStream
, обратитесь к link .