Вопрос по .net, memorystream – Сбросить или очистить .NET MemoryStream

43

.NET MemoryStream, по-видимому, не имеет метода .Reset или .Clear.

Я думал об использовании следующего кода для достижения этой цели:

ms.Seek(0, IO.SeekOrigin.Begin)
ms.SetLength(0)

Как правильно очистить или сбросить существующий .NET MemoryStream?

И код ОП является законным. .Capacity остается после этих инструкций, так что это лучший способ избежать free / alloc, когда в этом нет необходимости. CodeAngry
Просто чтобы прояснить этот вопрос. Я думаю, ему интересно, какой метод предотвращает выделение памяти. Теоретически,SetLength(0) должен сохранитьCapacity при назначенииnew MemoryStream() должен освободить эту память и выделить новое. В зависимости от использования можно сохранить память и просто сбросить потокLength а такжеPosition. (во всяком случае, так мог бы думать программист C ++, ориентирующийся на память) CodeAngry

Ваш Ответ

3   ответа
66

Или вы можете использовать:

memoryStream.SetLength(0);
Создание нового потока памяти вызывает выделение. Некоторые программы чувствительны к производительности, и каждое распределение имеет значение. Nic Foster
Это не работает, когда вы перечитываете данные в поток. Положение и длина будут 0! Martin.Martinsson
Наткнулся на это поздно, но Андрей прав. Оставив это здесь, так как я должен был проверить. MSDN: если указанное значение больше текущей емкости, а размер потока можно изменить, емкость увеличивается ... поток между старой и новой длиной инициализируется нулями. Rig
3

потому что он будет избыточным. Установив нулевую длину, вы очищаете его.

Конечно, вы всегда можете сделать:

memoryStream = new MemoryStream(memoryStream.Capacity());

Это даст вам поток памяти того же размера, который инициализирован.

Если вы действительно хотите очистить поток вручную, я подозреваю, что вам придется прибегнуть к циклическому прохождению элементов.

также не работает, если вы используете поток с оператором using. Предпочел бы .SetLenght (0) тоже Cadburry
Вот почему мой ответ указывает на то, что установка его на нулевую длину очищает его .. затем подробно рассказывается о том, как получить поток той же длины, который инициализируется конструктором. omglolbah
-1 Зачем новый поток такой же мощности, когда ты мог.SetLength(0); и сохранить емкость? Злоупотребление памятью в действии. CodeAngry
20

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

public static void Clear(this MemoryStream source)
{
  byte[] buffer = source.GetBuffer();
  Array.Clear(buffer, 0, buffer.Length);
  source.Position = 0;
  source.SetLength(0);
}

Неверно говорить, что только MemoryStream.SetLength сбрасывает или очищает MemoryStream, поскольку SetLength очищает внутренний буферный массив, только если длина превышает длину текущего буфера.

Реинициализация MemoryStream - это правильный подход, но менее эффективный. Одним из преимуществ повторной инициализации MemoryStream будет гарантия того, что поток никогда не будет закрыт. После закрытия MemoryStream его уже нельзя изменить. Если вы можете быть уверены, что экземпляр MemoryStream не закрыт, то очистка буфера может помочь.

установка длины в 0 также устанавливает позицию в 0, поэтому установка позиции избыточна Dmitry Dovgopoly
Просто хочу подчеркнуть важный момент: если вы используете буфер напрямую, выявляются на риск чтения «старых» данных, если вы не обнуляете буфер при сбросе позиции в ноль. Однако, если вы придерживаетесь методов Read (), этоне будет случается - байты после «конца» потока не копируются из одного буфера в другой. piers7
.Reset () не должен обнулять данные правильно? Только .Clear () должен делать это ... PS - Есть ли способ прочитать длину данных после закрытия потока? (т.е. без частной рефлексии, надеюсь) user645280
Всегда получая исключение для допустимого непустого потока при вызовеsource.GetBuffer(): Внутренний буфер MemoryStream недоступен. обнздесь объяснили почемуstackoverflow.com/a/1646219/44217 Mar

Похожие вопросы