Was genau bedeutet "Stream" und "Buffer" in Java I / O?

81

Ich habe gerade etwas über Eingabe / Ausgabe mit gelernt BufferedReader.

Ich wollte wissen, was genau die Bedeutung des Begriffs ist Streamund Buffer?

Auch was dient uns diese Codezeile:

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
user122345656
quelle

Antworten:

197

Java hat zwei Arten von Klassen für Eingabe und Ausgabe (E / A): Streams und Reader / Writer .

Bäche ( InputStream, OutputStreamund alles, was diese erstreckt) sind zum Lesen und Schreiben von binären Daten aus Dateien, das Netzwerk, oder was auch immer ein anderes Gerät.

Leser und Schriftsteller dienen zum Lesen und Schreiben von Text (Zeichen). Sie sind eine Schicht über Streams, die Binärdaten (Bytes) mithilfe einer Zeichencodierung in Zeichen und zurück konvertiert .

Das byteweise Lesen von Daten von der Festplatte ist sehr ineffizient. Eine Möglichkeit, dies zu beschleunigen, besteht darin, einen Puffer zu verwenden: Anstatt jeweils ein Byte zu lesen, lesen Sie einige tausend Bytes gleichzeitig und speichern sie in einem Puffer im Speicher. Dann können Sie die Bytes im Puffer einzeln betrachten.

Das Java-Tutorial von Oracle zu E / A erklärt dies ausführlich.

Betrachten Sie die von Ihnen angegebene Codezeile:

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

System.inist ein InputStream. Sie erstellen eine, aus InputStreamReaderder Bytes gelesen werden System.in. Dann wickeln Sie das in ein BufferedReader.

Am Ende haben Sie also eine BufferedReader, die von einer InputStreamReaderliest, die von liest System.in.

Jesper
quelle
1
Vielen Dank für Ihre Antwort, aber ich habe eine Verwirrung. Wie Sie sagten, lesen wir einige tausend Bytes gleichzeitig und legen sie in den Puffer. Bedeutet dies also, dass der Puffer nur ein Ort im Speicher ist, an dem wir Dinge speichern?
user122345656
3
@ Jesper. Sie sagten: "Eine Möglichkeit, dies zu beschleunigen, besteht darin, einen Puffer zu verwenden: Anstatt jeweils ein Byte zu lesen, lesen Sie einige tausend Bytes gleichzeitig und legen sie in einem Puffer im Speicher ab. Dann können Sie sich die Bytes ansehen im Puffer eins nach dem anderen. " Ja, es ist wahr, aber ich denke, mit Puffer wird auch ein einzelnes Byte gleichzeitig gelesen. Der einzige Unterschied, den ich denke, ist, dass es in den Puffer und das Programm gestellt wird und dann aus dem Puffer anstelle der Festplatte gelesen wird
M Sach
7
@ user122345656 Ja, ein Puffer ist ein Speicherplatz zum temporären Speichern von Daten.
Jesper
14
@MSach Überlegen Sie, was passiert, wenn Sie Daten von einer Festplatte lesen möchten. Um ein Byte an einer bestimmten Stelle zu lesen, müssen Sie warten, bis sich die Festplatte gedreht hat, bis sich der Kopf über der Stelle auf der Festplatte befindet, an der sich das zu lesende Byte befindet. Wenn Sie in diesem Moment nur 1 Byte und das nächste Byte später lesen würden, müssten Sie warten, bis die Festplatte eine vollständige Drehung ausgeführt hat, um das nächste Byte zu lesen. Es ist viel effizienter, einen Block aufeinanderfolgender Bytes zu lesen.
Jesper
2
@parsecer Streams dienen zum Lesen von Bytes. Leser sind zum Lesen von Text (Zeichen). InputStreamReaderist ein Wrapper um ein InputStream, mit dem Sie Text aus einem lesen können InputStream. Wenn Sie nur Bytes (keine Zeichen) lesen möchten, brauchen Sie keine InputStreamReader. Dies ist nützlich, wenn Sie die Bytes als Textzeichen interpretieren möchten.
Jesper
19

Puffer:

Dies ist ein Bereich eines physischen Speichers , in dem Daten vorübergehend gespeichert werden, während sie von einem Ort an einen anderen verschoben werden. Dieser physische Speicher wäre in den meisten Fällen RAM (Arbeitsspeicher).

Aus dem Kontext dieser Frage wird jedoch Puffer beim Lesen / Schreiben von Daten verwendet. Es muss nicht verwendet werden, wenn Daten von einem Ort an einen anderen verschoben werden.

Beispiel für einen Puffer: Wenn Ihr System über 4 GB RAM verfügt, können vom System 4 KB Arbeitsspeicher (RAM) für den Puffer zugewiesen werden. KB - Kilobyte (n), GB - Gigabyte (s)

E / A-Stream (oder) Stream:

Der E / A-Stream repräsentiert eine Eingabequelle oder ein Ausgabeziel. Ein Stream kann viele verschiedene Arten von Quellen und Zielen darstellen, einschließlich Festplattendateien, Geräten, anderen Programmen und Speicherarrays.

E / A bedeutet Eingabe / Ausgabe.

Der Eingabestream kann also eine Eingabequelle wie eine Festplattendatei, eine Netzwerkverbindung usw. sein.

Der Ausgabestream kann ein Ausgabeziel wie eine Festplattendatei, eine Netzwerkverbindung usw. sein.

Laut der offiziellen Dokumentation von JAVA gibt es drei Arten von Streams.

  1. Byte-Streams (Lesen oder Schreiben von Bytes)
  2. Zeichenströme ( Zeichen lesen oder schreiben)
  3. Gepufferte Streams (aus Effizienzgründen aus dem Puffer lesen oder in diesen schreiben )

Byte-Streams:

Sie führen die Eingabe und Ausgabe von 8-Bit-Bytes durch. Alle Byte-Stream-Klassen stammen von InputStream und OutputStream ab .

Byte Input Stream-Klassen erhalten die Eingabe als Rohbytes . Byte-Ausgabe Stream-Klassen geben die Ausgabe als Rohbytes an .

InputStream- Direkt bekannte Unterklassen

AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream.

OutputStream- Direkt bekannte Unterklassen

ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, OutputStream, PipedOutputStream

Charakter-Streams: Sie sind eine Ebene über Byte-Streams. Sie konvertieren Bytes (Binärdaten) in Zeichen und Zeichen in Bytes unter Verwendung einer Zeichencodierung.

Alle Zeichenstromklassen stammen von Reader und Writer ab .

Reader - Direkt bekannte Unterklassen

BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader

Writer - Direkt bekannte Unterklassen

BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

Byte Bäche & Character Streams verwenden ungepufferte E / A .

Dies bedeutet, dass jede Lese- oder Schreibanforderung direkt vom zugrunde liegenden Betriebssystem verarbeitet wird. Dies kann ein Programm viel weniger effizient machen, da jede solche Anforderung häufig den Festplattenzugriff, die Netzwerkaktivität oder eine andere Operation auslöst, die relativ teuer ist. Um diesen Overhead zu reduzieren, implementiert die Java-Plattform gepufferte E / A-Streams.

Gepufferte Streams:

Gepufferte Eingabeströme lesen Daten aus einem Speicherbereich, der als Puffer bekannt ist . Die native Eingabe-API wird nur aufgerufen, wenn der Puffer leer ist.

In ähnlicher Weise schreiben gepufferte Ausgabestreams Daten in einen Puffer , und die native Ausgabe-API wird nur aufgerufen, wenn der Puffer voll ist.

Ein Programm kann einen ungepufferten Stream unter Verwendung der Umbruchsprache in einen gepufferten Stream konvertieren , wobei das ungepufferte Stream-Objekt für eine gepufferte Stream-Klasse an den Konstruktor übergeben wird .

Beispiel:

inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));

Es gibt 4 gepufferte Stream-Klassen, die zum Umschließen ungepufferter Streams verwendet werden:

Verwenden Sie zum Erstellen gepufferter Byte-StreamsBufferedInputStream und BufferedOutputStreamKlassen.

Verwenden Sie zum Erstellen gepufferter ZeichenströmeBufferedReader und BufferedWriterKlassen.

AnV
quelle
1
Ich suchte nach einer so ausführlichen Erklärung für Java Io. Vielen Dank.
Arif Reza
14

Nun, es ist eine Frage für jeden, der anfängt, an java.io zu arbeiten. Um Ihre Fragen zu beantworten, stellen InputStreamReader und BufferedReader nur die Java-Objekte dar (sie haben nichts Besonderes), sie werden jedoch für Io-Vorgänge wie Lesen und Schreiben von / zu verschiedenen Ein- / Ausgängen wie Datei, Objekt usw. Erstellt

Kommen wir nun zur Linie

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

InputStreamReader ist die Klasse zum Lesen des Eingabestreams von Bytes. Das Lesen jedes Bytes ist jedoch eine teure Operation, daher wickeln wir es um BufferedReader, um es zu puffern (was ein Dekorationsmuster ist).

Noch bevor Sie mit dem Lesen beginnen, speichert bufferedReader einen Teil der Bytes im Register und wenn Sie den Lesevorgang ausführen. Es wird von diesem Speicherort gelesen, der viel billiger ist als das Lesen von der Konsole / Datei. Im Fall von InputStreamReader wird jedoch bei jedem Festplattenzugriffsvorgang ein Lesevorgang ausgeführt

M Sach
quelle
+1, aber ich würde es vorziehen, wenn Links Links für den Info-Dekorateur hinzugefügt worden wären und jedes Mal, wenn ein Datenträgerzugriff stattfindet, Sentances stattfinden
Shareef
Dieser letzte Absatz fasst die Vorteile gut zusammen. Danke für das.
Dave Voyles
3

Ein Stream ist die Verbindung und die tatsächlichen Informationen, die zwischen Punkten übertragen werden. Der Puffer ist ein Speichercontainer, der einen Teil oder die gesamten gestreamten Daten speichert und diese dem Ausgabegerät zuführt.

Der Punkt ist natürlich, dass die Ausgabe pausieren würde, wenn der Stream über die zum Anzeigen der Daten erforderliche Datenrate hinaus verlangsamt. Der Puffer verhindert dies.

PGallagher
quelle
Vielen Dank für Ihre Antwort. Aber eine Frage, die mir in den Sinn kam, ist, was Sie unter gestreamten Daten verstehen.
user122345656
1
Entschuldigung für die späte Antwort. Wenn Sie sich ein einfaches Beispiel für eine 10-MB-Datei auf dem Server vorstellen. Der Server verfügt über die vollständige Datei, kann jedoch nicht die gesamte Datei in einem Paket senden. Stattdessen wird die Datei in eine endliche Anzahl von Blöcken aufgeteilt. Jeder Block wird dann an den Remotecomputer gesendet und wieder zusammengesetzt. Für das Streaming von Live-Daten gilt dieselbe Theorie. Der Server nimmt jedoch die Live-Daten und sendet sie als streamPakete. Der entfernte Computer speichert dann jedes Paket in einem Puffer. Der Remote-Computer liest die Daten aus seinem Puffer und erstellt daraus beispielsweise ein Video. Ich hoffe das hilft!
PGallagher
1

Ein Puffer ist ein Teil im Speicher, der zum Speichern eines Datenstroms von Peripheriegeräten verwendet wird. Aus diesem Puffer wird dann dieser Datenstrom gesammelt und in Variablen gespeichert. Ein Stream kann als kontinuierlicher Datenfluss definiert werden.

Der Begriff „Eingabe / Ausgabe“ bedeutet nichts anderes als das Verschieben von Daten in und aus Puffern. Behalte das einfach die ganze Zeit im Kopf. Prozesse führen E / A durch, indem sie vom Betriebssystem anfordern, dass Daten aus einem Puffer entleert werden (Schreibvorgang) oder dass ein Puffer mit Daten gefüllt wird (Lesevorgang).
Logisches Diagramm, wie sich Daten bewegen

Stellen Sie sich in einfachen Worten vor, wenn Sie Daten über eine Tastatur eingeben, werden die Daten über eine Pipe (den Stream ) in den Puffer und dann vom Puffer auf die Festplatte übertragen (Schreibvorgang). Wenn Daten von der Festplatte zum Puffer und vom Puffer zur Konsole verschoben werden, handelt es sich ebenfalls um eine Leseoperation.

Sie können die Links zum besseren Verständnis lesen. Ich hoffe es hilft!.
Was ist Puffer in Java? Geben Sie
hier die Linkbeschreibung ein

Kushagra
quelle