C # mit Streams

116

Streams sind für mich irgendwie mysteriös. Ich weiß nicht, wann ich welchen Stream verwenden soll und wie ich sie verwenden soll. Kann mir jemand erklären, wie Streams verwendet werden?

Wenn ich das richtig verstehe, gibt es drei Stream-Typen:

  • stream
  • read stream
  • write stream

Ist das richtig? Und was ist zum Beispiel der Unterschied zwischen a Memorystreamund a FileStream?

Martijn
quelle
13
Vielleicht möchten Sie stackoverflow.com/questions/507747/…
Preets
3
Nehmen Sie ein Array von Bytes und erstellen Sie einen Wrapper dafür ( Stream), der einige hilfreiche Methoden wie Lesen, Schreiben und Ändern der Position aufzeigt. Jetzt können Sie Klassen basierend auf ihrem Sicherungsspeicher (FileStream, MemoryStream) erstellen, die Streamdiese Funktionalität basierend auf dem jeweiligen Sicherungsspeicher erben und darauf aufbauen.
Der Muffin-Mann

Antworten:

80

Ein Stream ist ein Objekt, mit dem Daten übertragen werden. Es gibt eine generische Stream-Klasse System.IO.Stream, von der alle anderen Stream-Klassen in .NET abgeleitet sind. Die StreamKlasse befasst sich mit Bytes.

Die konkreten Stream-Klassen werden verwendet, um mit anderen Datentypen als Bytes umzugehen. Beispielsweise:

  • Die FileStreamKlasse wird verwendet, wenn die externe Quelle eine Datei ist
  • MemoryStream wird verwendet, um Daten im Speicher zu speichern
  • System.Net.Sockets.NetworkStream verarbeitet Netzwerkdaten

Reader / Writer-Streams wie StreamReaderund StreamWritersind keine Streams - sie sind nicht abgeleitet von System.IO.Stream, sie sollen helfen, Daten von und zu streamen und zu lesen!

Arsen Mkrtchyan
quelle
3
Wenn ich das richtig verstehe, enthält der Stream die Daten und macht nichts damit. Die "Helfer" -Klassen von Lesern und Schreibern können die Daten im Stream verarbeiten (manipulieren).
Martijn
9
Nein, Stream ist kein Datencontainer, sondern dient zum Übertragen von Daten. Beispielsweise überträgt FileStream Daten von Byte [] in eine physische Datei, NetworkStream überträgt Byte [] per Socket. Reader Writer-Klassen sind Hilfsklassen zum Schreiben und Lesen aus dem Stream. Beispielsweise kann StreamReader zum Lesen aus dem Stream-String und nicht aus Byte [] verwendet werden. Wenn Sie FileStream als Parameter angeben, wird es aus File gelesen, wenn NetworkStream aus Socket.
Arsen Mkrtchyan
Darüber hinaus dienen StreamReader und StreamWriter zum Lesen und Schreiben von TEXT-Streams (Zeichen).
1c1cle
1
Es gibt einen guten Artikel, der Ihnen hilft, MemoryStream zu verstehen. codeproject.com/Articles/832387/…
Jiaji Li
2
@ user420667. gute Frage. In den Fällen AudioStream und TemperatureStream handelt es sich höchstwahrscheinlich um BinaryStreams für den Treiber, der dem Gerät zugeordnet ist. Sie können auch einen CustomStream erstellen, der speziell für die Benutzeroberfläche erstellt wurde.
1c1cle
62

Um andere Antworten hier ein wenig zu erweitern und einen Großteil des Beispielcodes zu erklären, über den Sie gepunktet sehen, lesen und schreiben Sie die meiste Zeit nicht direkt in einen Stream. Streams sind ein einfaches Mittel zum Übertragen von Daten.

Sie werden feststellen, dass die Funktionen zum Lesen und Schreiben alle byteorientiert sind, z. B. WriteByte (). Es gibt keine Funktionen für den Umgang mit Ganzzahlen, Zeichenfolgen usw. Dies macht den Stream sehr universell, aber weniger einfach zu bearbeiten, wenn Sie beispielsweise nur Text übertragen möchten.

.NET bietet jedoch Klassen, die zwischen nativen Typen und der Stream-Schnittstelle auf niedriger Ebene konvertieren und die Daten für Sie zum oder vom Stream übertragen. Einige bemerkenswerte solche Klassen sind:

StreamWriter // Badly named. Should be TextWriter.
StreamReader // Badly named. Should be TextReader.
BinaryWriter
BinaryReader

Um diese zu verwenden, erwerben Sie zuerst Ihren Stream, erstellen dann eine der oben genannten Klassen und ordnen sie dem Stream zu. Z.B

MemoryStream memoryStream = new MemoryStream();
StreamWriter myStreamWriter = new StreamWriter(memoryStream);

StreamReader und StreamWriter konvertieren zwischen nativen Typen und ihren Zeichenfolgendarstellungen und übertragen dann die Zeichenfolgen als Bytes zum und vom Stream. So

myStreamWriter.Write(123);

schreibt "123" (drei Zeichen '1', '2', dann '3') in den Stream. Wenn Sie mit Textdateien (z. B. HTML) arbeiten, sind StreamReader und StreamWriter die Klassen, die Sie verwenden würden.

Wohingegen

myBinaryWriter.Write(123);

schreibt vier Bytes, die den 32-Bit-Ganzzahlwert 123 (0x7B, 0x00, 0x00, 0x00) darstellen. Wenn Sie mit Binärdateien oder Netzwerkprotokollen arbeiten, können Sie BinaryReader und BinaryWriter verwenden. (Wenn Sie Daten mit Netzwerken oder anderen Systemen austauschen, müssen Sie auf Endianness achten , aber das ist ein anderer Beitrag.)

Tim Williams
quelle
StreamWriter- und Reader-Adapterklassen sind ernsthaft schlecht benannt. Danke, dass du das erwähnt hast. Wie sie auf diesen Namen gekommen sind, überrascht mich immer noch.
Tarik
Auch die binären Writer- und Reader-Klassen sind schlecht benannt.
Tarik
22

Streams eignen sich gut für den Umgang mit großen Datenmengen. Wenn es unpraktisch ist, alle Daten gleichzeitig in den Speicher zu laden, können Sie sie als Stream öffnen und mit kleinen Teilen davon arbeiten.

Fleischpflanze
quelle
1
Würde gerne ein Beispiel von dem sehen, was Sie gerade gesagt haben "Arbeiten Sie mit kleinen Stücken davon".
Jenna Leaf
2
Streams eignen sich auch für kleine Datenmengen. Wenn ein C # -Programmierer den Inhalt einer Datei bearbeiten möchte, muss er unabhängig von der Datenmenge Streams verwenden. Die gleiche Aussage gilt auch für Netzwerkströme. Zugegeben, wenn der Programmierer eine niedrigere Sprache wie C codiert, ist es möglich, Zeichen oder Bytes direkt auf eine Festplatte oder einen Socket zu schreiben, aber selbst für eine kleine Datenmenge ist dies zeitaufwändig und anfälliger Error.
1c1cle
10

Stream ist nur eine Abstraktion (oder ein Wrapper) über einen physicalBytestrom. Dieser physicalStream heißt der base stream. So gibt es immer einen Basisstrom über die ein Stream Wrapper erstellt wird , und somit wird die Umhüllung nach dem Basisstrom - Typ namens dh FileStream, MemoryStreamusw.

Der Vorteil des Stream-Wrappers besteht darin, dass Sie eine einheitliche API erhalten, mit der Sie mit Streams aller zugrunde liegenden Typen usb, fileusw. interagieren können .

Warum sollten Sie Daten als Stream behandeln? Da Datenblöcke bei Bedarf geladen werden, können wir die Daten als Blöcke untersuchen / verarbeiten, anstatt die gesamten Daten in den Speicher zu laden. So gehen die meisten Programme mit großen Dateien um, z. B. zum Verschlüsseln einer Betriebssystem-Image-Datei.

Anwar Husain
quelle
4

Es gibt nur einen Grundtyp von Stream. Unter verschiedenen Umständen lösen einige Mitglieder beim Aufruf eine Ausnahme aus, da in diesem Zusammenhang die Operation nicht verfügbar war.

Zum Beispiel MemoryStreamist a einfach eine Möglichkeit, Bytes in einen Speicherblock hinein und aus diesem heraus zu verschieben. Daher können Sie Read and Write darauf aufrufen.

Auf der anderen Seite FileStreamkönnen Sie mit a aus einer Datei lesen oder schreiben (oder beides). Ob Sie tatsächlich lesen oder schreiben können, hängt davon ab, wie die Datei geöffnet wurde. Sie können nicht in eine Datei schreiben, wenn Sie sie nur für den Lesezugriff geöffnet haben.

AnthonyWJones
quelle
3

Ich würde zunächst die Streams auf MSDN nachlesen: http://msdn.microsoft.com/en-us/library/system.io.stream.aspx

Memorystream und FileStream sind Streams, die zum Arbeiten mit Rohspeicher bzw. Dateien verwendet werden ...

Robban
quelle
Danke für den Link. Ich fand es toll, dass "Sie den Quellcode online durchsuchen, die Referenz für die Offline-Anzeige herunterladen und während des Debuggens durch die Quellen (einschließlich Patches und Updates) gehen können". Diese Funktion bietet einen neuen Einblick.
David
1

Ich würde diese verschiedenen Arten von Streams nicht nennen. Die Stream-Klasse verfügt über CanRead- und CanWrite-Eigenschaften, die angeben, ob der bestimmte Stream gelesen und beschrieben werden kann.

Der Hauptunterschied zwischen verschiedenen Stream-Klassen (wie MemoryStream und FileStream) ist der Sicherungsspeicher - aus dem die Daten gelesen oder in den sie geschrieben werden. Es ist irgendwie offensichtlich aus dem Namen. Ein MemoryStream speichert die Daten nur im Speicher, ein FileStream wird durch eine Datei auf der Festplatte gesichert, ein NetworkStream liest Daten aus dem Netzwerk und so weiter.

Mattias S.
quelle