Ответ 1
Здесь реализация CopyTo
в .NET 4.5:
private void InternalCopyTo(Stream destination, int bufferSize)
{
int num;
byte[] buffer = new byte[bufferSize];
while ((num = this.Read(buffer, 0, buffer.Length)) != 0)
{
destination.Write(buffer, 0, num);
}
}
Итак, как вы можете видеть, он читается из источника, а затем записывается в пункт назначения. Вероятно, это может быть улучшено;)
EDIT: здесь возможна реализация версии с каналами:
public static void CopyToPiped(this Stream source, Stream destination, int bufferSize = 0x14000)
{
byte[] readBuffer = new byte[bufferSize];
byte[] writeBuffer = new byte[bufferSize];
int bytesRead = source.Read(readBuffer, 0, bufferSize);
while (bytesRead > 0)
{
Swap(ref readBuffer, ref writeBuffer);
var iar = destination.BeginWrite(writeBuffer, 0, bytesRead, null, null);
bytesRead = source.Read(readBuffer, 0, bufferSize);
destination.EndWrite(iar);
}
}
static void Swap<T>(ref T x, ref T y)
{
T tmp = x;
x = y;
y = tmp;
}
В принципе, он синхронно считывает блок, начинает асинхронно копировать его в пункт назначения, затем читает следующий фрагмент и ждет завершения записи.
Я провел несколько тестов производительности:
- используя
MemoryStream
s, я не ожидал значительного улучшения, поскольку он не использует порты завершения ввода-вывода (AFAIK); и действительно, производительность почти идентична. - используя файлы на разных дисках, я ожидал, что версия с каналами будет работать лучше, но она не... на самом деле немного медленнее (на 5-10%).
Таким образом, это, по-видимому, не приносит никакой пользы, что, вероятно, является причиной того, что он не реализован таким образом...