2009-12-19 9 views
17

Una conveniencia útil introducida en .NET 4 es Stream.CopyTo(Stream[, Int32]) que lee el contenido de la secuencia actual y lo escribe en otra secuencia.¿Cómo se implementa el método Stream.CopyTo (Stream) en .NET 4?

Esto evita la necesidad de un poco tediosa code such as this:

public static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[32768]; 
    while (true) 
    { 
     int read = input.Read (buffer, 0, buffer.Length); 
     if (read <= 0) 
      return; 
     output.Write (buffer, 0, read); 
    } 
} 

Dado que no tengo .NET 4 instalado en este equipo, me preguntaba si alguien que tiene .NET 4 instalado podría abrir reflector y mostrarnos cómo el equipo de Framework Class Library implementó este método para .NET 4.

Compare y contraste su implementación con el fragmento de código anterior. En particular, me interesa saber qué tamaño de búfer predeterminado se eligió.

+0

¿funciona la copia en el flujo de red? – Benny

+0

Buena pregunta. No estoy seguro ... ¿tal vez una de las personas con .NET 4 instalado puede probarlo? –

+0

parece que puede funcionar en el flujo de red. – Benny

Respuesta

16

En .NET 4.5.1, utiliza un tamaño de búfer fijo de 81920 bytes. (Las versiones anteriores de .NET usaban un tamaño de búfer fijo de 4096 bytes, y sin duda continuará cambiando con el tiempo). También existe una sobrecarga en la que puede pasar su propio tamaño de búfer.

La implementación es muy similar a la tuya, modulo algunos arrastrando los pies y algunas comprobaciones de errores. Reflector hace que el corazón de la siguiente manera: (. Ahora puede ver la fuente real en http://referencesource.microsoft.com/#mscorlib/system/io/stream.cs#98ac7cf3acb04bb1)

private void InternalCopyTo(Stream destination, int bufferSize) 
{ 
    int num; 
    byte[] buffer = new byte[bufferSize]; 
    while ((num = this.Read(buffer, 0, buffer.Length)) != 0) 
    { 
    destination.Write(buffer, 0, num); 
    } 
} 

La comprobación de errores es, básicamente, en torno a si input.CanRead y output.CanWrite son verdaderas, o cualquiera de ellos está dispuesto. Entonces, en respuesta a la pregunta de Benny, esto debería ser una copia perfectamente feliz de un NetworkStream (o de un NetworkStream grabable).

+0

Supongo que la idea es usar exactamente 1 página para el buffer? – Yuliy

+4

Es un "número feliz" para tamaños de búfer. Es muy poco probable que caiga exactamente en un límite de página. –

+1

También es lo suficientemente pequeño como para no ser asignado en el montón de objetos grandes. – skolima

Cuestiones relacionadas