Повторное использование потоков памяти

Предположим, что я скопировал байтовый буфер в поток памяти, используя этот

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