2012-05-18 3 views
24

У меня есть HttpHandler, возвращающий изображение через Response.OutputStream. У меня есть следующий код:Разница между Stream.CopyTo и MemoryStream.WriteTo

_imageProvider.GetImage().CopyTo(context.Response.OutputStream); 

GetImage() метод возвращает Stream, который на самом деле является MemoryStream экземпляр и возвращает 0 байт в браузере. Если я изменить GetImage() сигнатуру метода для возврата MemoryStream и используйте следующую строку кода:

_imageProvider.GetImage().WriteTo(context.Response.OutputStream); 

Он работает и браузер получает изображение. Итак, какова разница между WriteTo и CopyTo в классе MemoryStream, и каков рекомендуемый способ сделать это, используя класс Stream в методе метода GetImage().

ответ

38

WriteTo() сбрасывает позицию считывания до нуля перед копированием данных. С другой стороны, CopyTo() скопирует любые данные после текущей позиции в потоке. Это означает, что если вы не сбросили позицию самостоятельно, данные не будут прочитаны вообще.

Скорее всего, вы просто пропустите следующий в первой версии:

memoryStream.Position = 0; 
+1

Я думаю, что copyTo сохраняет источник, а writeto is not. –

+5

, где вы получили эту информацию? не могли бы вы предоставить ссылку? –

+0

Мне хотелось бы, чтобы мозг мозга имел общедоступную ссылку. – viento

9

Согласно отражателем, это CopyTo() определение метода:

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); 
    } 
} 

Я не вижу какой-либо «остается механизм «здесь ... Он копирует все от this до места назначения (в блоках размера буфера).

+0

@nonnb печать экран? документация ? –

+0

извинения, пожалуйста, проигнорируйте мой комментарий - моя ошибка - я копировал между 2 фильтрами и забыл перемотать один из потоков до вызова CopyTo. CopyTo работает так, как вы + BrokenGlass описали – StuartLC

+4

Просто чтобы страница была последовательной: описанный метод _IternalCopyTo_ _Reads_ из текущего потока в буфер - чтение начинается с текущей позиции потока (параметры индекса и смещения являются индексом и смещением в буфере) - то есть "механизм останков" –