Как удалить данные из MemoryStream

#c# #.net #memorystream

#c# #.net #memorystream

Вопрос:

Я не могу заставить это работать. У меня есть объект MemoryStream. Этот класс имеет свойство Position, которое сообщает вам, сколько байтов вы прочитали.

Что я хочу сделать, так это удалить все байты между 0 и позицией-1

Я пробовал это:

 MemoryStream ms = ...
ms.SetLength(ms.Length - ms.Position);
  

но в какой-то момент мои данные повреждаются.

Итак, я закончил тем, что сделал это

 MemoryStream ms = ...
byte[] rest = new byte[ms.Length - ms.Position];
ms.Read(rest, 0, (int)(ms.Length - ms.Position));
ms.Dispose();
ms = new MemoryStream();
ms.Write(rest, 0, rest.Length);
  

который работает, но на самом деле не эффективен.

Есть идеи, как я могу заставить это работать?

Спасибо

Ответ №1:

Это должно сработать и быть намного эффективнее, чем создание нового буфера:

 byte[] buf = ms.GetBuffer();            
Buffer.BlockCopy(buf, numberOfBytesToRemove, buf, 0, (int)ms.Length - numberOfBytesToRemove);
ms.SetLength(ms.Length - numberOfBytesToRemove);
  

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

Конечно, вам нужно быть осторожным с проблемами, выходящими за рамки.

Ответ №2:

Вы не можете удалить данные из MemoryStream — самым чистым было бы создать новый поток памяти на основе нужных вам данных:

 MemoryStream ms = new MemoryStream(someData);
//ms.Position changes here
//...
byte[] data = ms.ToArray().Skip((int)ms.Position).ToArray();
ms = new MemoryStream(data);
  

Комментарии:

1. Вы уверены в этом? Итак, что делает SetLength? Спасибо

2. @Moonlit — вы можете усекать данные, но не удалять произвольные блоки, вам нужно скопировать данные тем или иным способом. Сказав, что мой код ничуть не лучше вашего (кроме того, что вы полагаетесь ms.Read() на копирование всех байтов)

Ответ №3:

Вызов ms.SetLength(ms.Length - ms.Position) не удалит байты между 0 и ms.Position-1 , фактически он удалит байты между ms.Length - ms.Position и ms.Length .

Почему бы просто не написать:

 byte[] rest;
ms.Write(rest, ms.Length-ms.Position, rest.Length);
  

Комментарии:

1. Спасибо за объяснение метода SetLength

Ответ №4:

  var _ = new MemoryStream();
 _.Write(buf.GetBuffer(), (int)buf.Position, (int)buf.Length - (int)buf.Position);
 buf = _;