2012-05-30 9 views
7

Ich verwende einen BinaryReader über einem NetworkStream, um Daten aus einem Netzwerk zu lesen. Das hat wirklich gut für mich funktioniert, aber ich möchte verstehen, was hinter den Kulissen vor sich geht, also habe ich mir die Dokumentation für BinaryReader angeschaut und herausgefunden, dass sie extrem spärlich ist.Was macht BinaryReader, wenn die gelesenen Bytes noch nicht vorhanden sind?

Meine Frage ist dies: Was wird BinaryReader.ReadBytes(bufferSize) tun, wenn bufferSize Bytes nicht im Netzwerkstream vorhanden sind, wenn ich ReadBytes aufrufen?

In meinem Kopf gibt es ein paar Optionen:
1) alle Bytes lesen, die auf dem Netzwerk-Stream vorhanden sind und nur zurück, dass viele
2) Warten Sie, bis bufferSize Bytes vorhanden auf dem Strom sind, dann lesen Sie
3) Werfen Sie eine Ausnahme

Ich gehe davon aus, Option 2 passiert, da ich noch keine Ausnahmen erhalten habe und alle meine Daten empfangen werden, nicht in Stücken. Ich würde jedoch gerne wissen, was vor sich geht. Wenn mich jemand aufklären könnte, wäre ich dankbar.

+2

Es wird blockieren und sicherstellen, dass Sie die angeforderte Anzahl von Bytes erhalten. Sie erhalten nur weniger, wenn der Stream geschlossen wurde und Sie alle gelesen haben. –

Antwort

9

Ich glaube es geht tatsächlich für versteckte Option 4:

  • die Daten lesen, sobald sie verfügbar wird, Looping Runde in der gleichen Weise, die Sie normalerweise manuell tun würden. Es gibt nur einen Wert zurück, der kleiner ist als die Anzahl der Bytes, die Sie angefordert haben, wenn der Wert des Streams beim Lesen erreicht wird.

Dies ist auf subtile Weise unterscheidet sich von Ihrer Option 2, da es tut den Strom zu entwässern als Daten verfügbar ist - es nicht warten, bis es alle Daten in einem Rutsch lesen konnte.

Es ist leicht zu zeigen, dass es eine geringere Anzahl von Bytes zurückgibt, als Sie gefragt, ob es das Ende erreicht:

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

Es ist schwieriger, die Looping-Teil zu beweisen, ohne benutzerdefinierten Strom, würde ausdrücklich erfordern mehrere Read Aufrufe, um alle Daten zurückzugeben.

Die Dokumentation ist nicht so klar, wie es sein könnte, aber der Rückgabewert Teil ist zumindest etwas hilfreich:

ein Byte-Array ausgelesenen Daten von dem darunterliegenden Stream enthält. Dies ist möglicherweise weniger als die Anzahl der angeforderten Bytes , wenn das Ende des Streams erreicht ist.

Hinweis der letzte Teil, die ich hervorgehoben habe, und vergleichen Sie das mit Stream.Read:

Die Gesamtzahl der Bytes in den Puffer gelesen. Dies kann weniger als die Anzahl der angeforderten Bytes sein, wenn diese Anzahl an Bytes derzeit nicht verfügbar ist, oder null (0), wenn das Ende des Streams erreicht wurde.

Wenn Sie eine genaue Datenmenge erwar und nur die Menge von Nutzen sein wird, empfehle ich Ihnen eine ReadExactly Methode schreiben, die Read nennt und wirft EndOfStreamException, wenn Sie mehr Daten als der Strom, bevor es zur Verfügung gestellt brauchen war geschlossen.

+0

Danke für das Detail in Ihrer Antwort. Ich habe jedoch eine schnelle, einfache Frage. Das Ende des Streams wird nur erreicht, wenn der Stream geschlossen ist, richtig? – Darkhydro

+0

@Darkhydro: Oder wenn die Netzwerkverbindung unterbrochen ist, ja. –

0

Wenn Sie bei "im Stream vorhanden" angeben, ob die Methode blockieren würde, bis die angegebene Anzahl von Bytes verfügbar ist, ist dies Option 2. Sie würde nur eine kleinere Anzahl an Bytes zurückgeben, wenn die Ende des Streams ist erreicht.

Hier einige Beispiel-Code auf, wie BinaryReader.ReadBytes(int) implementiert werden kann:

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; 
} 
Verwandte Themen