2010-03-17 22 views
34

.NET MemoryStream no parece tener un método .Reset o .Clear.Restablecer o borrar .NET MemoryStream

Yo estaba pensando en usar el siguiente código para lograr esto:

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

¿Cuál es la forma correcta para borrar o restablecer una MemoryStream .NET existente?

+3

** Solo para aclarar esta pregunta. ** Creo que se pregunta qué método impide que se asigne la memoria. En teoría, 'SetLength (0)' debe retener 'Capacity' al asignar un' nuevo MemoryStream() 'debería liberar esta memoria y asignar nueva. Dependiendo del uso, es posible que desee preservar la memoria y simplemente restablecer 'Longitud' y' Posición' de la secuencia. * (de todos modos, así es como pensaría un programador de C++ consciente de la memoria) * – CodeAngry

+1

** Y el código del OP es legítimo. ** '.Capacity' permanece después de esas instrucciones, así que es la mejor manera de evitar un free/alloc cuando no es necesario . – CodeAngry

Respuesta

6

La memoria no tiene un método de reinicio/borrado porque sería redundante. Al configurarlo a cero, lo borra.

Por supuesto, siempre se puede hacer:

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

Esto le daría una MemoryStream del mismo tamaño que se inicializa.

Si realmente quieres borrar manualmente la secuencia, sospecho que tendrías que recurrir a recorrer los elementos.

+11

-1 ¿Por qué un nuevo flujo de la misma capacidad cuando podía '.SetLength (0);' y conservar la capacidad? Abuso de memoria en acción. – CodeAngry

+0

tampoco funciona si usa la secuencia con una instrucción using. Preferiría .SetLenght (0) también – Cadburry

+0

Es por eso que mi respuesta indica que establecerlo en longitud cero lo borra ... luego explica cómo obtener un flujo de la misma longitud que el constructor inicializa. – omglolbah

59

¿Por qué necesita restablecer la secuencia de la memoria? Siempre puedes crear uno nuevo. O puede usar:

memoryStream.SetLength(0); 
+1

Es cierto, pero no responde mi pregunta. ¿Cómo puedo restablecer mi MemoryStream existente? –

+4

Creo que Setlength (0) debería funcionar para usted. –

+0

Llegó tarde pero Andrew está en lo correcto. Dejando esto aquí ya que tuve que verificar. MSDN: si el valor especificado es mayor que la capacidad actual y la secuencia se puede cambiar de tamaño, la capacidad aumenta ... la secuencia entre la longitud anterior y la nueva se inicializan en ceros. – Rig

18

Dado que un MemoryStream es esencialmente un conjunto de bytes con un índice (y algunos otros miembros de soporte), borrar el conjunto de bytes y restablecer el índice se puede considerar restablecer y borrar el MemoryStream. Si el estado inicial de un MemoryStream es una matriz de puesta a cero con una posición de cero, entonces un ejemplo de un restablecimiento MemoryStream puede ser:

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

Es incorrecto decir que MemoryStream.SetLength solamente restablece o borra la MemoryStream desde SetLength solo borra la matriz de búfer interna si la longitud excede la longitud actual del búfer.

La reinicialización de un MemoryStream es un enfoque válido pero menos eficiente. Un beneficio de reiniciar el MemoryStream sería garantizar que el flujo nunca se cerró. Una vez que MemoryStream está cerrado, ya no se puede cambiar. Si puede asegurarse de que la instancia de MemoryStream no se cierre, borrar el buffer puede ser el camino a seguir.

+0

.Reset() no debería estar poniendo a cero los datos ¿verdad? Solo .Clear() debería hacer eso ... PS: ¿Alguna forma de leer la longitud de los datos después de que se cierre la transmisión? (es decir: sin reflexión privada con suerte) –

+0

Solo quiero subrayar un punto importante aquí: si utiliza el búfer directamente, * corre el riesgo * de leer datos "antiguos" si no pone a cero el búfer cuando restablece la posición a cero. Sin embargo, si se limita a usar los métodos Read(), esto * no ocurrirá *: los bytes que pasan del 'final' de la secuencia no se copian de un buffer a otro. – piers7

+0

Obteniendo siempre una excepción para un flujo no vacío válido cuando se invoca el buffer interno 'source.GetBuffer()': _MemoryStream_. ** upd **: aquí se explica por qué: http://stackoverflow.com/a/1646219/44217 – Mar

Cuestiones relacionadas