2012-05-30 13 views
7

Sto utilizzando un BinaryReader su un NetworkStream per leggere i dati su una rete. Questo ha funzionato molto bene per me, ma voglio capire cosa succede dietro le quinte, quindi ho dato un'occhiata alla documentazione di BinaryReader e l'ho trovato estremamente scarso.Cosa fa BinaryReader se i byte che sto leggendo non sono ancora presenti?

mia domanda è questa: che cosa fare se BinaryReader.ReadBytes(bufferSize)bufferSize byte non sono presenti sul flusso di rete quando chiamo ReadBytes?

Nella mia mente ci sono alcune opzioni:
1) legge le byte che sono presenti sul flusso di rete e restituire solo che molti
2) Attendere bufferSize byte sono presenti sul torrente, poi leggere
3) un'eccezione

presumo l'opzione 2 sta accadendo, dal momento che non ho mai ricevuto alcuna eccezione e tutti i miei dati ricevuto insieme, non a pezzi. Tuttavia, mi piacerebbe sapere con certezza cosa sta succedendo. Se qualcuno potesse illuminarmi, sarei grato.

+2

Blocca e garantisce di ottenere il numero di byte richiesto. Ottieni meno se il flusso si chiude e tu li hai letti tutti. –

risposta

9

Credo che realtà vale per l'opzione nascosta 4:

  • leggere i dati non appena disponibili, looping arrotondare nello stesso modo in cui normalmente si farebbe manualmente. Restituirà un valore inferiore al numero di byte richiesto se raggiunge fine dello stream durante la lettura.

Questo è sottilmente diverso dal vostra opzione 2 in quanto fa drenare il flusso come dati diventa disponibile - non aspettare fino a quando non in grado di leggere tutti i dati in una sola volta.

E 'facile dimostrare che non restituisce un minor numero di byte che avete chiesto se si raggiunge la fine:

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

E' più difficile da dimostrare la parte di loop, senza un flusso personalizzato che avrebbe esplicitamente richiedere più chiamate Read per restituire tutti i dati.

La documentazione non è chiaro come potrebbe essere, ma la parte valore restituito è almeno alquanto utile:

Matrice di byte contenente dati letti dal flusso sottostante. Questo potrebbe essere inferiore al numero di byte richiesto se viene raggiunta la fine dello stream.

Nota la parte finale che ho evidenziato, e confrontare che con Stream.Read:

Il numero totale di byte letti nel buffer. Questo può essere inferiore al numero di byte richiesto se molti byte non sono attualmente disponibili o zero (0) se è stata raggiunta la fine del flusso.

Se vi aspettate una quantità esatta di dati e solo tale importo possa essere utile, vi consiglio di scrivere un metodo che chiama ReadExactlyRead e getta EndOfStreamException se avete bisogno di più dati rispetto al flusso fornito prima che era chiuso.

+0

Grazie per il dettaglio nella risposta. Comunque ho una domanda facile e veloce. La fine del flusso viene raggiunta solo se lo stream è chiuso, corretto? – Darkhydro

+0

@Darkhydro: O se la connessione di rete è interrotta, sì. –

0

Se, "presente sullo stream", si sta chiedendo se il metodo potrebbe bloccare fino a quando il numero specificato di byte è disponibile, allora è l'opzione 2. Restituisce solo una quantità inferiore di byte se lo fine dello stream è stato raggiunto.

Ecco alcuni esempi di codice su come possono essere attuate BinaryReader.ReadBytes(int):

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; 
} 
Problemi correlati