2012-05-30 14 views
7

Estoy usando un BinaryReader en la parte superior de un NetworkStream para leer datos de una red. Esto ha funcionado muy bien para mí, pero quiero entender lo que está sucediendo detrás de escena, así que eché un vistazo a la documentación de BinaryReader y me pareció extremadamente escasa.¿Qué hace BinaryReader si los bytes que estoy leyendo todavía no están presentes?

Mi pregunta es esta: ¿Qué hará BinaryReader.ReadBytes(bufferSize) si bufferSize bytes no están presentes en la transmisión de red cuando llamo al ReadBytes?

En mi mente hay algunas opciones:
1) Leer los bytes que están presentes en la corriente de la red y devolver sólo que muchos
2) Espere hasta que bufferSize bytes están presentes en la corriente, a continuación, leer
3) Lanzar una excepción

Supongo que la opción 2 está sucediendo, ya que nunca he recibido ninguna excepción y todos mis datos se reciben enteros, no en pedazos. Sin embargo, me gustaría saber con certeza qué está pasando. Si alguien pudiera iluminarme, estaría agradecido.

+2

Bloqueará y se asegurará de que obtenga el número solicitado de bytes. Solo obtendrá menos si la transmisión se cerró y usted los ha leído todos. –

Respuesta

9

creo que realidad ocurre con la opción oculto 4:

  • leer los datos a medida que esté disponible, de enlace redondear de la misma manera que lo haría normalmente de forma manual. Solo devolverá un valor menor que el número de bytes que solicitó si alcanza el final de la transmisión durante la lectura.

Esta es sutilmente diferente a la opción 2, ya que hace drenar la corriente que se disponga de datos - no espere hasta que se pudiera leer todos los datos de una sola vez.

Es fácil demostrar que no devuelven un menor número de bytes que usted pidió si se llega al final:

var ms = new MemoryStream(new byte[10]); 
var readData = new BinaryReader(ms).ReadBytes(100); 
Console.WriteLine(readData.Length); // 10 

Es más difícil de probar la parte de bucle, sin un flujo costumbre que lo haría de manera explícita requiere llamadas múltiples Read para devolver todos los datos.

La documentación no es tan clara como podría ser, pero la parte de valor de retorno es al menos un poco útil:

una matriz de bytes que contiene los datos leídos de la corriente subyacente. Esto podría ser menor que el número de bytes solicitados si se llega al final de la secuencia.

Nota la parte final que yo he resaltado, y compararlo con Stream.Read:

El número total de bytes leídos en el buffer. Esto puede ser menor que el número de bytes solicitados si muchos bytes no están actualmente disponibles, o cero (0) si se ha alcanzado el final de la secuencia.

Si usted está esperando una cantidad exacta de datos y solamente esa cantidad será útil, le sugiero que escribe un método que llama a ReadExactlyRead y lanza EndOfStreamException si necesita más datos que la corriente proporcionada antes de que se estaba cerrado.

+0

Gracias por los detalles en su respuesta. Sin embargo, tengo una pregunta rápida y fácil. El final de la transmisión solo se alcanza si la transmisión está cerrada, ¿correcto? – Darkhydro

+0

@Darkhydro: O si la conexión de red está rota, sí. –

0

Si, por "presente en la secuencia", está preguntando si el método se bloquearía hasta que el número de bytes especificado esté disponible, entonces es la opción 2. Devolvería una cantidad menor de bytes si el se llega al final de la transmisión.

Aquí hay un código de ejemplo de cómo BinaryReader.ReadBytes(int) puede implementarse:

byte[] ReadBytes(int count) 
{ 
    byte[] buffer = new byte[count]; 
    int total = 0; 
    int read = 0; 

    do 
    { 
     read = stream.Read(buffer, read, count - total); 
     total += read; 
    } 
    while (read > 0 && total < count); 

    // Resize buffer if smaller than count (code not shown). 

    return buffer; 
} 
Cuestiones relacionadas