Повторное использование потоков памяти
Предположим, что я скопировал байтовый буфер в поток памяти, используя этот
memoryStream.Read(data, 0, data.Length);
Есть ли способ освободить поток и повторно использовать его для чтения дополнительных данных?
Я хочу избежать создания многих объектов MemoryStream и предпочитаю использовать один экземпляр, сбросив его между обычаями
Ответы
Ответ 1
Вы можете установить Position
в 0, это приведет к действию reset потока.
Однако, как указывает этот ответ, повторное использование потоков памяти вряд ли принесет вам какие-либо выгоды от производительности. Дешевле создавать больше потоков памяти.
Другим вариантом является использование закрепленного byte[]
в качестве вашего буфера для повторного использования.
Ответ 2
Вы можете повторно использовать MemoryStream, установив позицию в 0 и длину в 0.
MemoryStream ms = new MemoryStream();
// Do some stuff with the stream
// Reset the stream so you can re-use it
ms.Position = 0; // Not actually needed, SetLength(0) will reset the Position anyway
ms.SetLength(0);
// Do some more stuff with the stream
Установив длину в 0, вы не очищаете существующий буфер, он только сбрасывает внутренние счетчики. Таким образом, существующее распределение буфера остается неповрежденным, но все бухгалтерские данные о том, какая часть буфера используется, reset, чтобы вы могли повторно использовать его.
Обновление: Я просто быстро просмотрел реализацию кода для SetLength, и если вы установите длину в 0, позиция автоматически будет reset до 0, поэтому вам даже не нужно явно указывать установите для свойства Position достаточно всего reset длины.
Ответ 3
Было бы лучше использовать memoryStream.getBuffer()
и смещения/длину (используйте memoryStream.Position
и memoryStream.Length
для обнаружения границ) для прямого доступа к данным byte[]
, Reader
/Writer
/BinaryFormatter
classes, или другие классы, принимающие Stream
, для чтения/записи примитивных/сложных типов в буфер (для чего создан MemoryStream
), вы управляете без бесполезных операций копирования, потому что MemoryStream
уже основан на байтовом массиве.
Я использовал его таким образом с асинхронными операциями сокета send/receive, принимающими byte[]
, но будьте осторожны - если вы написали что-то в буфер за пределами его текущего Length
и хотите увеличить его длину с помощью SetLength()
для чтения с классом Reader - вы получаете очень неудобное поведение (на мой взгляд) - этот метод аннулирует каждый байт между старой длиной и новой длиной, если длина увеличивается.
Я решил эту проблему, изменив исходный код (один Array.Clear вызов в SetLength()
и некоторые дополнения для управления без внутренних классов .NET) MemoryStream
и используя его в моем проекте.
Что касается повторного использования MemoryStream, я согласен с ответом Криса Тейлора (SetLength(0)
)
Ответ 4
memoryStream.Seek(0, SeekOrigin.Begin);