2009-10-27 10 views
8

Como discussed before, cuando un BinaryReader o BinaryWriter se cierra, su Stream subyacente se cierra también (aargh). Considere esta situación: una rutina R se pasa un MemoryStream, digamos M; Me gustaría escribir algunas cosas en M y luego pasarlo a otra rutina para más procesamiento (no necesariamente escribir). Para mayor comodidad, me gustaría envolver M en un BinaryWriter para hacer mi escritura. Después de escribir, he terminado con el BinaryWriter pero no con M.¿Cómo "bifurco" un Stream en .NET?

void R(MemoryStream M) 
{ 
    using (B = new BinaryWriter(M)) 
    { 
     // write some stuff using B 
    } 

    S(M); // now pass M to another routine for further processing 
} 

Pero, no puedo disponer de la BinaryStream sin cerrar M.

P: ¿Hay alguna manera de hacer algo de lo siguiente?

  • extraer el byte subyacente [] de una MemoryStream,
  • clon de una secuencia
  • reabrir una corriente después de que se ha cerrado
+0

No sé C#, pero en Java, simplemente abandonarías sin cerrar el BinaryWriter. ¿No usa {...} construir fuerza de cierre? ¡Entonces no uses esa construcción! –

+0

P.S. Pero debes asegurarte de limpiar el BinaryWriter antes de abandonarlo. –

Respuesta

2

Gracias a varios que sugirieron ToArray, me llevaron a la respuesta correcta, que es `M.GetBuffer '. ToArray no es tan malo, pero

  • hace una copia
  • obtiene sólo una parte de la memoria intermedia

GetBuffer simplemente agarra una referencia al byte subyacente [], que es lo que soy después.

+0

que se indicó en mi respuesta ;) –

0

A algo enfoque ingenuo es utilizar

byte buf[] = MemoryStream.ToArray(); 

Para copiar el contenido de la secuencia a una matriz de bytes. Puede convertir de nuevo en un arroyo con

MemoryStream ms = new MemoryStream(buf); 
+0

Vale la pena enfatizar: este método funciona tanto en una transmisión cerrada como en una transmisión en vivo. –

2

Puede:

  • llamada M.ToArray() para obtener la corriente como una matriz de bytes.
  • Subclase BinaryWriter y reemplazar el método Dispose para evitar el cierre de la corriente de niño
+0

+1 específicamente para la anulación de eliminación. –

+0

¿No puedes evitar llamar cerca/Eliminar? –

-1

Accoring a this M.Clone(); Deberia trabajar. Pero puedo estar equivocado ...

+0

-1 para publicar en un sitio web que no permite ver sus contenidos de forma gratuita, lo cual es bastante inútil –

7

Usted debe obtener el mejor [] buffer de bytes subyacente utilizando

byte[] buffer = ms.GetBuffer(); 

y luego copiar los datos de bytes mediante el método Array.Copy(). Usted es libre de crear una nueva corriente con él.

+0

No entiendo por qué está diciendo que es mejor usar GetBuffer y luego hacer una copia usando Array.Copia. Si quisiera una copia, solo usaría ToArray. –

+0

de MSDN doc Este método omite los bytes no utilizados en MemoryStream de la matriz. Para obtener el buffer completo, use el método GetBuffer. http://msdn.microsoft.com/en-us/library/system.io.memorystream.toarray.aspx –

+0

El "Método anterior" se refiere al MemoryStream.ToArray() –

5

Puede usar cosas como la MiscUtil.IO.NonClosingStreamWrapper en MiscUtil, que envuelve un Stream y simplemente ignora Close/Dispose solicitudes. Por solo este propósito.

void R(MemoryStream M) 
{ 
    using (B = new BinaryWriter(new NonClosingStreamWrapper(M))) 
    { 
     // write some stuff using B 
    } 

    S(M); // now pass M to another routine for further processing 
}  
1

sólo para añadir que aquí, una solución muy simple sería no a dispose() del escritor.

void R(MemoryStream M) 
{ 
    B = new BinaryWriter(M); 

    // write some stuff using B   
    B.Flush(); 
    S(M); // now pass M to another routine for further processing 
} 

Ahora solo tiene que preocuparse de mantener B en el alcance, que será durante R().

Puede que esta no sea la mejor solución aquí, pero vale la pena señalar que los lectores y escritores no necesitan deshacerse de sí mismos.

+0

Esperemos que 'BinaryWriter' no almacene nada en el búfer, entonces ... –

+0

Pero asegúrese de llamar a B.flush() después de que haya terminado con esto en caso de que no haya pasado todo a M. (Eso es lo que se necesitaría en Java, ni idea de C#) –

+0

OK, Adrian y Marc, me olvidé de Flush(). –

Cuestiones relacionadas