2009-11-12 15 views
5

Angenommen, wir haben ein Codeblock wie folgt aus:-Stream lesen Problem

//Assuming s is a stream: 
byte[] data = new byte[1000]; 
s.Read(data,0,data.Length); 

die Read-Methode überall 1-1000 Bytes lesen konnte, ungelesen die Balance des Stroms zu verlassen.

Dies ist, was ein C# Buch sagt.

Ich verstehe nicht, warum Read Methode würde irgendwo aus dem Stream lesen? Es liest nicht den gesamten Stream?

Und es sagt die Behelfslösung so sein sollte:

//bytesRead will always end up at 1000, unless the stream is itself smaller in length: 
int bytesRead = 0; 
int chunkSize = 1; 
while(bytesRead < data.Length && chunkSize > 0) 
     bytesRead += chunkSize = s.Read(data,bytesRead,dataLength-bytesRead); 

Dieser Code wird auch durch das Buch als Behelfslösung zur Verfügung gestellt. Was ich versuche zu verstehen, ob die Read-Methode beginnt, bis zum Ende zu lesen und alle Bytes im angegebenen Bereich in Byte-Array zu schreiben. Warum benutzt er die bytesRead als Startpunkt in s.Read(data,bytesRead,dataLength-bytesRead);

Vielen Dank im Voraus.

Antwort

8

Die Idee ist, dass die Daten möglicherweise nicht verfügbar sind, wenn Sie Read ... oder überhaupt aufrufen. In einem NetworkStream können die Daten beispielsweise langsamer ankommen als Sie abholen. Oder Sie befinden sich nahe am Ende eines FileStreams. Der Stream kann wissen, dass weniger Bytes übrig sind, als Sie angefordert haben, oder er hat möglicherweise keine Möglichkeit zu wissen, wann und ob die volle Anzahl an angeforderten Bytes ankommen wird. Anstatt also auf Daten zu warten, die möglicherweise nie ankommen, oder mit einem Fehler "Nicht genug Bytes, rate again" zu scheitern, behält sich Read das Recht vor, weniger als die angeforderten zurückzugeben.

Wenn Sie daher einen Chunk in ein Bytearray einlesen, füllen Sie möglicherweise das Bytearray nicht aus. Aber Sie möchten, dass der nächste Chunk an die Stelle des letzten Chunks angehängt wird, anstatt den Anfang des Byte-Arrays zu überschreiben. Daher übergeben Sie bytesRead als Startposition für das Platzieren des nächsten Chunks im Bytearray.

0

Basierend auf meiner Lektüre der Dokumentation für die Read-Methode, da Streams zum Lesen unterschiedlichster Datenquellen verwendet werden können, von der Tastatureingabe über Dateien bis zum Netzwerkverkehr, wurde der spezifischen Implementierung offen gelassen, ob Daten zurückgegeben werden Die read-Methode gibt die angeforderte Anzahl an Bytes zurück. Wenn beispielsweise eine bestimmte Implementierung zum Lesen von Netzwerkdaten die 500 Datenbyte zurückgeben möchte, die bisher für eine Webanforderung verfügbar waren, erwartet sie jedoch, dass sie erst ausgeführt wird, wenn sie 1000 Byte gelesen hat und Sie 1000 angefordert haben Bytes, es kann zurückgeben, was es hat, damit Sie es verarbeiten können. Es wird Ihnen sagen, dass es nur 500 Bytes liest, und Sie sollten wissen, dass es mehr auf dem Weg sein kann. Das Maximum von 1000 ist nur ein Hinweis darauf, dass Sie nicht mehr als 1000 Byte gleichzeitig verarbeiten möchten.

2

Das erste Beispiel verwendet die angegebene Größe des Byte-Arrays von 1000 als Eingabeparameter in die Read-Methode. Das zweite Beispiel liest den Stream ein Byte nach dem anderen, was großartig für das Streaming von eingehenden oder ausgehenden Daten ist - das bedeutet, wenn Sie Teile des empfangenen Streams verarbeiten können, ohne zuerst alles vollständig in den Speicher zu puffern, ist dies a effizienterer Ansatz.

Ich denke, wo Sie hier verwirrt werden, ist, dass der Autor das Beispiel künstlich auf maximal 1000 Bytes beschränkt.Viele Protokolle, die das Streaming beinhalten, senden in der Regel anfangs ein oder zwei Bytes, um den Verbraucher über die Länge des gesamten Streams zu informieren, damit er den Stream am besten aufteilen und verarbeiten kann, so dass kein deklariertes Limit von 1.000 erforderlich ist. Sie erhalten die Größe, Sie chunks es entsprechend (einschließlich der letzte Chunk, die möglicherweise nicht vollständige Chunk-Größe), und verarbeiten Sie jeden Chunk.

+0

Sie meinen, zuerst senden sie die Größe der Daten, die sie senden möchten, und dann senden sie die ganzen Daten als Stücke, anstatt sie als Ganzes zu senden? – Tarik

+0

Normalerweise ja. Angenommen, Sie haben eine 40-MB-Datei auf der Festplatte, die Sie übertragen möchten. Anstatt 40 MB in den Speicher zu laden und sie dann zu übertragen - und damit 40 MB Speicher für eine gewisse Zeit voll zu machen - liest man einfach, sagen wir die ersten 1024 Bytes, überträgt es und fährt mit 1024 Byte-Blöcken fort. Ein Dateiübertragungsprotokoll kann angeben, dass "die ersten zwei Bytes des ersten Pakets ein vorzeichenloses int enthalten, das die Größe der Nutzlast angibt", sodass Sie wissen, wann Sie aus diesem Stream lesen können. Das empfangende Ende kann dasselbe tun - es in 1024 Bytes oder eine andere ressourcenfreundliche Puffernummer zerstückeln. – cfeduke

1

Ich verstehe nicht, warum Read-Methode würde irgendwo aus dem Stream lesen? Es wird nicht der gesamte Stream gelesen?

Lesen ermöglicht Ihnen, Start- und Endpunkte zum Lesen anzugeben. Weitere Informationen finden Sie in itowlson's Antwort.

Was ich versuche, ob zu verstehen Lesen Methode das Ende zu lesen beginnt und alle Bytes in spezifizierten Bereich Byte-Array zu schreiben.

Wenn das eine Frage war, nehme ich an, die Antwort ist nein. Die Read-Methode füllt ein Array mit Daten aus einem Stream an den angegebenen Start- und Endpunkten.

Warum verwendet er die BytesRead als Startpunkt in s.Read (Daten, BytesRead, DataLength-BytesRead);

Er verwendet BytesRead, um "die Menge der gelesenen Bytes" zu verfolgen. Dadurch weiß er, wo er beim nächsten Leseanruf zu lesen beginnt.

4

Der Ausdruck "könnte irgendwo von 1 bis 1000 Bytes lesen" bedeutet "könnte 1 Byte lesen, oder 2 Bytes, bis zu 1000 Bytes". Es bezieht sich auf die Länge Bytes gelesen, nicht die Position. Der Wert wird an der aktuellen Position des Streams sein.