2011-04-24 19 views
15

Supongamos que he copiado un búfer de bytes en un flujo de memoria al utilizar estareutilización de memoria corrientes

memoryStream.Read(data, 0, data.Length); 

¿Hay alguna manera para mí para vaciar la corriente y volver a utilizarlo para leer datos adicionales?

que quieren evitar la creación de muchos objetos MemoryStream y prefieren utilizar un caso, ponerlo a cero entre usos

Respuesta

16

Puede configurar el Position a 0, esto a su efecto de restablecer la corriente.

Sin embargo, como this respuesta indica, la reutilización de las corrientes de memoria no es probable que obtener cualquier beneficio de rendimiento. Es más barato crear más flujos de memoria.

Otra opción es usar un pin byte[] como su memoria intermedia para su reutilización.

+1

Claro - Pero si la corriente ya contiene 100 bytes y escribo 99 bytes a continuación, cuando llegue a leer el contenido de esta corriente Leeré demasiado :) –

+1

@CycleMachine - hay una razón por la que reiniciar/borrar flujos de memoria no está incorporada. Vea la respuesta vinculada que he agregado. – Oded

+3

Si asigna un buffer grande, sería más eficiente reutilizar el buffer frente a la reasignación cada vez. En lugar de establecer la posición, puede usar SetLength (0) (ver mi respuesta a continuación) que mantendrá el búfer asignado y restablecerá los contadores internos, la longitud y la posición, lo que es más barato que la reasignación de un búfer grande con frecuencia. –

-1

memoryStream.Seek (0, SeekOrigin.Begin);

19

Se puede volver a utilizar el MemoryStream por Ajuste de la posición a 0 y la longitud de 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 

Al establecer la longitud a 0 que no vacía el búfer existente, sólo se restablece los contadores internos . Por lo tanto, la asignación de búfer existente permanece intacta, pero toda la contabilidad de la cantidad de búfer utilizada se restablece para que pueda volver a utilizarla.

Actualización: que acaba de tomar un rápido vistazo a la implementación del código de SetLength y si se establece la longitud a 0 la posición será automáticamente pone a 0 por lo que ni siquiera es necesario establecer explícitamente la propiedad de posición es lo suficiente como para restablecer la longitud.

0

Sería mejor si se utiliza memoryStream.getBuffer() y compensaciones/longitud (uso memoryStream.Position y memoryStream.Length para la detección de límites) para acceder directamente byte[] datos, Reader/Writer/BinaryFormatter clases, u otras clases de aceptar Stream, para la lectura/escritura primitiva/tipos complejos en memoria intermedia (eso es lo que se hace para MemoryStream), que gestionan operaciones de copia sin inútiles, porque ya MemoryStream se basa en la matriz de bytes.

he usado de esta manera con el envío asíncrono/recibir operaciones con conectores aceptar byte[], pero cuidado - si escribió algo en el tapón más allá de su actual Length y quieren aumentar su longitud con SetLength() para leer con la clase de lector - se obtiene muy incómodo comportamiento (en mi opinión): este método anula cada byte entre la longitud antigua y la nueva longitud si la longitud aumenta.

Resolvió este problema modificando el código fuente (una llamada Array.Clear en SetLength(), y algunas adiciones para administrar sin clases internas de .NET) de MemoryStream y usándolo en mi proyecto.

En cuanto a la reutilización de MemoryStream, estoy de acuerdo con la respuesta de Chris Taylor (SetLength(0))