Antworten:
Ein Stream repräsentiert eine Folge von Objekten (normalerweise Bytes, aber nicht unbedingt), auf die in sequentieller Reihenfolge zugegriffen werden kann. Typische Operationen in einem Stream:
Ein bestimmter Stream unterstützt möglicherweise das Lesen (in diesem Fall handelt es sich um einen "Eingabestream"), das Schreiben ("Ausgabestream") oder beides. Nicht alle Streams sind durchsuchbar.
Push-Back ist ziemlich selten, aber Sie können es jederzeit einem Stream hinzufügen, indem Sie den realen Eingabestream in einen anderen Eingabestream einschließen, der einen internen Puffer enthält. Lesevorgänge kommen aus dem Puffer, und wenn Sie zurückschieben, werden Daten in den Puffer gestellt. Wenn sich nichts im Puffer befindet, liest der Push-Back-Stream aus dem realen Stream. Dies ist ein einfaches Beispiel für einen "Stream-Adapter": Er befindet sich am "Ende" eines Eingabestreams, ist selbst ein Eingabestream und macht etwas Besonderes, das der ursprüngliche Stream nicht getan hat.
Stream ist eine nützliche Abstraktion, da es Dateien (die wirklich Arrays sind, daher ist das Suchen unkompliziert), aber auch Terminal-Ein- / Ausgabe (die nur durchsucht werden kann, wenn sie gepuffert sind), Sockets, serielle Schnittstellen usw. beschreiben kann. Sie können also Code schreiben, der besagt Entweder "Ich möchte einige Daten, und es ist mir egal, woher sie kommen oder wie sie hierher gekommen sind" oder "Ich werde einige Daten produzieren und es liegt ganz bei meinem Anrufer, was damit passiert". Ersteres verwendet einen Eingabestream-Parameter, letzteres einen Ausgabestream-Parameter.
Die beste Analogie, die ich mir vorstellen kann, ist, dass ein Strom ein Förderband ist, das auf Sie zukommt oder von Ihnen wegführt (oder manchmal beides). Sie entfernen Inhalte aus einem Eingabestream, Sie fügen Inhalte in einen Ausgabestream ein. Einige Förderer, die Sie sich vorstellen können, kommen aus einem Loch in der Wand - sie sind nicht suchbar, Lesen oder Schreiben ist ein einmaliger Deal. Einige Förderer sind vor Ihnen angeordnet, und Sie können den Aufenthaltsort in dem Stream auswählen, den Sie lesen / schreiben möchten - das ist die Suche.
Wie IRBMe jedoch sagt, ist es am besten, sich einen Stream in Bezug auf die von ihm angebotenen Operationen vorzustellen (die von Implementierung zu Implementierung variieren, aber viel gemeinsam haben) und nicht durch eine physikalische Analogie. Streams sind "Dinge, die man lesen oder schreiben kann". Wenn Sie mit dem Anschließen von Stream-Adaptern beginnen, können Sie sich diese als eine Box mit einem Förderer in und einem Förderer aus vorstellen, die Sie mit anderen Streams verbinden. Anschließend führt die Box eine Transformation der Daten durch (Komprimieren oder Ändern von UNIX-Zeilenvorschüben) zu DOS oder was auch immer). Pipes sind ein weiterer gründlicher Test der Metapher: Hier erstellen Sie ein Paar Streams, sodass alles, was Sie in einen schreiben, aus dem anderen ausgelesen werden kann. Denk an Wurmlöcher :-)
Ein Stream ist bereits eine Metapher, eine Analogie, so dass es wirklich nicht nötig ist, einen anderen zu veröffentlichen. Sie können es sich im Grunde als ein Rohr mit einem Wasserfluss vorstellen, in dem das Wasser tatsächlich Daten und das Rohr der Strom ist. Ich nehme an, es ist eine Art 2-Wege-Rohr, wenn der Strom bidirektional ist. Es ist im Grunde eine übliche Abstraktion, die auf Dinge angewendet wird, bei denen ein Datenfluss oder eine Folge von Daten in eine oder beide Richtungen vorliegt.
In Sprachen wie C #, VB.Net, C ++, Java usw. wird die Stream-Metapher für viele Dinge verwendet. Es gibt Dateistreams, in denen Sie eine Datei öffnen und kontinuierlich aus dem Stream lesen oder darauf schreiben können. Es gibt Netzwerk-Streams, in denen das Lesen von und das Schreiben in den Stream von einer zugrunde liegenden etablierten Netzwerkverbindung liest und in diese schreibt. Streams, die nur zum Schreiben verwendet werden, werden normalerweise wie in diesem Beispiel als Ausgabestreams bezeichnet. In ähnlicher Weise werden Streams, die nur zum Lesen bestimmt sind, wie in diesem Beispiel als Eingabestreams bezeichnet .
Ein Stream kann eine Transformation oder Codierung von Daten durchführen (ein SslStream in .Net verschlingt beispielsweise die SSL-Verhandlungsdaten und verbirgt sie vor Ihnen; Ein TelnetStream kann die Telnet-Verhandlungen vor Ihnen verbergen, bietet jedoch Zugriff auf die Daten; A. Mit ZipOutputStream in Java können Sie in Dateien in einem Zip-Archiv schreiben, ohne sich um die Interna des Zip-Dateiformats kümmern zu müssen.
Eine andere häufige Sache, die Sie möglicherweise finden, sind Text-Streams, mit denen Sie Zeichenfolgen anstelle von Bytes schreiben können, oder einige Sprachen bieten Binär-Streams, mit denen Sie primitive Typen schreiben können. Eine häufige Sache, die Sie in Textströmen finden, ist eine Zeichenkodierung, die Sie kennen sollten.
Einige Streams unterstützen auch den Direktzugriff, wie in diesem Beispiel. Ein Netzwerk-Stream hingegen würde dies aus offensichtlichen Gründen nicht tun.
UNIX-ähnliche Betriebssysteme unterstützen auch das Stream-Modell mit Programmeingabe und -ausgabe, wie hier beschrieben .
Die bisher gegebenen Antworten sind ausgezeichnet. Ich stelle nur eine andere zur Verfügung, um hervorzuheben, dass ein Stream keine Folge von Bytes oder spezifisch für eine Programmiersprache ist, da das Konzept universell ist (während seine Implementierung möglicherweise eindeutig ist). Ich sehe online oft eine Fülle von Erklärungen in Bezug auf SQL, C oder Java, die sinnvoll sind, da sich ein Dateistream mit Speicherorten und Operationen auf niedriger Ebene befasst. Sie befassen sich jedoch häufig mit der Erstellung eines Dateistreams und der Bearbeitung der potenziellen Datei in der angegebenen Sprache, anstatt das Konzept eines Streams zu diskutieren.
Wie bereits erwähnt, stream
ist a eine Metapher, eine Abstraktion von etwas Komplexerem. Um Ihre Fantasie zum Laufen zu bringen, biete ich einige andere Metaphern an:
Der Schlauch ist der Strom
Der Schlauch, die Düse und die zugehörigen Mechanismen, damit das Gas in Ihren Tank strömen kann, sind der Strom
Die Autobahn ist der Strom
Deine Ohren und Augen sind Ströme
Hoffentlich bemerken Sie in diesen Beispielen, dass die Stream-Metaphern nur existieren, um etwas durch sie hindurch zu lassen (oder im Fall der Autobahn darauf) und nicht selbst immer das darstellen, was sie übertragen. Eine wichtige Unterscheidung. Wir bezeichnen unsere Ohren nicht als eine Folge von Wörtern. Ein Schlauch ist immer noch ein Schlauch, wenn kein Wasser durch ihn fließt, aber wir müssen ihn an einen Zapfen anschließen, damit er seine Arbeit korrekt erledigt. Ein Auto ist nicht die einzige Art von Fahrzeug, die eine Autobahn überqueren kann.
Somit kann ein Stream existieren, durch den keine Daten übertragen werden, solange er mit einer Datei verbunden ist .
Als nächstes müssen wir einige Fragen beantworten. Ich werde Dateien verwenden, um Streams zu beschreiben, also ... Was ist eine Datei? Und wie lesen wir eine Datei? Ich werde versuchen, dies unter Beibehaltung eines bestimmten Abstraktionsniveaus zu beantworten, um unnötige Komplexität zu vermeiden, und das Konzept einer Datei aufgrund ihrer Einfachheit und Zugänglichkeit relativ zu einem Linux-Betriebssystem verwenden.
Eine Datei ist eine Abstraktion :)
Oder, so einfach ich erklären kann, ist eine Datei eine Teiledatenstruktur, die die Datei beschreibt, und ein Teil Daten, die den eigentlichen Inhalt darstellen.
Der Datenstrukturteil (in UNIX / Linux-Systemen als Inode bezeichnet) identifiziert wichtige Informationen zum Inhalt, enthält jedoch nicht den Inhalt selbst (oder einen Namen der Datei). Eine der darin enthaltenen Informationen ist eine Speicheradresse, an der der Inhalt beginnt. Mit einem Dateinamen (oder einem festen Link unter Linux), einem Dateideskriptor (einem numerischen Dateinamen, den das Betriebssystem interessiert) und einem Startort im Speicher haben wir etwas, das wir als Datei bezeichnen können.
(Der Schlüssel zum Mitnehmen ist, dass eine 'Datei' vom Betriebssystem definiert wird, da es das Betriebssystem ist, das sich letztendlich damit befassen muss. Und ja, Dateien sind viel komplexer.)
So weit, ist es gut. Aber wie bekommen wir den Inhalt der Datei, sagen Sie Ihrem Freund einen Liebesbrief, damit wir ihn ausdrucken können?
Wenn wir vom Ergebnis ausgehen und rückwärts gehen, wird beim Öffnen einer Datei auf unserem Computer der gesamte Inhalt auf unseren Bildschirm gespritzt, damit wir ihn lesen können. Aber wie? Sehr methodisch ist die Antwort. Der Inhalt der Datei selbst ist eine andere Datenstruktur. Angenommen, ein Array von Zeichen. Wir können uns das auch als String vorstellen.
Wie lesen wir diesen String? Indem Sie den Speicherort im Speicher finden und unsere Zeichenreihe zeichenweise durchlaufen, bis Sie ein Zeichen am Ende der Datei erreicht haben. Mit anderen Worten ein Programm.
Ein Stream wird beim Aufrufen seines Programms erstellt und verfügt über einen Speicherort, an den eine Verbindung hergestellt oder eine Verbindung hergestellt werden kann . Ähnlich wie in unserem Beispiel für einen Wasserschlauch ist der Schlauch unwirksam, wenn er nicht an einen Zapfen angeschlossen ist. Im Fall des Streams muss er mit einer Datei verbunden sein, damit er existiert.
Streams können weiter verfeinert werden, z. B. ein Stream zum Empfangen von Eingaben oder ein Stream zum Senden von Dateiinhalten an die Standardausgabe. UNIX / Linux verbindet und hält 3 Dateistreams für uns auf Anhieb offen, stdin (Standardeingabe), stdout (Standardeingabe) und stderr (Standardfehler). Streams können als Datenstrukturen selbst oder als Objekte erstellt werden, wodurch wir komplexere Operationen des durch sie gestreamten Datenstroms ausführen können, z. B. das Öffnen des Streams, das Schließen des Streams oder die Fehlerprüfung der Datei, mit der ein Stream verbunden ist. C ++ cin
ist ein Beispiel für ein Stream-Objekt.
Wenn Sie dies wünschen, können Sie sicherlich Ihren eigenen Stream schreiben.
Ein Stream ist ein wiederverwendbarer Code, der die Komplexität des Umgangs mit Daten abstrahiert und gleichzeitig nützliche Operationen für Daten bereitstellt.
Eine andere Analogie: Sie können nicht gegen einen Stream schwimmen, deshalb können Sie nur das nächste Bit, Byte, String oder Objekt aus dem Stream nehmen, während die bereits gelesenen Daten gelöscht werden. Ein One-Way-Ticket ... oder im Grunde nur eine Warteschlange ohne Speicherung von Persistenz.
Brauchen wir also Warteschlangen? Du entscheidest.
Das Wort "Stream" wurde gewählt, weil es (im wirklichen Leben) eine sehr ähnliche Bedeutung hat wie das, was wir vermitteln wollen, wenn wir es verwenden.
Denken Sie über die Analogie zu einem Wasserstrom nach. Sie erhalten einen kontinuierlichen Datenfluss, genau wie Wasser kontinuierlich in einem Fluss fließt. Sie wissen nicht unbedingt, woher die Daten stammen, und müssen dies meistens nicht. Sei es aus einer Datei, einem Socket oder einer anderen Quelle, es spielt keine Rolle (sollte). Dies ist sehr ähnlich wie das Empfangen eines Wasserstroms, wobei Sie nicht wissen müssen, woher es kommt. sei es aus einem See, einem Brunnen oder einer anderen Quelle, es spielt keine Rolle (sollte). Quelle