11 Stimmen

Wie unterscheidet sich java.io.Buffer* stream von normalen Streams?

1) Wie funktionieren gepufferte Streams im Hintergrund, wie unterscheiden sie sich von normalen Streams und was sind die Vorteile ihrer Verwendung?

2) DataInputStream ist auch Byte basiert. Aber es gibt Methoden, um readLine() . Was soll das Ganze hier?

8voto

Mark Punkte 28072

Aus der Javadoc von BufferedInputStream:

Ein BufferedInputStream fügt einem anderen Eingabestrom Funktionen hinzu, nämlich die Fähigkeit, die Eingabe zu puffern und die Markierungs- und Rücksetzmethoden zu unterstützen. Wenn der BufferedInputStream erstellt wird, wird ein internes Puffer-Array erstellt. Wenn Bytes aus dem Stream gelesen oder übersprungen werden, wird der interne Puffer nach Bedarf aus dem enthaltenen Eingabestrom aufgefüllt, und zwar viele Bytes auf einmal. Die Markierungsoperation merkt sich einen Punkt im Eingabestrom, und die Reset-Operation bewirkt, dass alle seit der letzten Markierungsoperation gelesenen Bytes erneut gelesen werden, bevor neue Bytes aus dem enthaltenen Eingabestrom entnommen werden.

Intern wird ein Puffer-Array verwendet, und anstatt einzelne Bytes aus dem zugrunde liegenden Eingabestrom zu lesen, werden so viele Bytes gelesen, dass der Puffer gefüllt wird. Dies führt im Allgemeinen zu einer schnelleren Leistung, da weniger Lesevorgänge im zugrunde liegenden Eingabestrom erforderlich sind.

Das Gegenteil gilt dann für BufferedOutputStream.

mark() und reset() könnten wie folgt verwendet werden:

1 BufferedInputStream bis = new BufferedInputStream(is);
2 byte[] b = new byte[4];
3 bis.read(b); // read 4 bytes into b
4 bis.mark(10); // mark the stream at the current position - we can read 10 bytes before the mark point becomes invalid
5 bis.read(b); // read another 4 bytes into b
6 bis.reset(); // resets the position in the stream back to when mark was called
7 bis.read(b); // re-read the same 4 bytes as line 5 into b

Um Markierung/Rückstellung näher zu erklären...

Der BufferInputStream merkt sich intern die aktuelle Position im Puffer. Wenn Sie Bytes lesen, wird die Position erhöht. Ein Aufruf von mark(10) speichert die aktuelle Position. Nachfolgende Aufrufe von read erhöhen die aktuelle Position weiter, aber ein Aufruf von reset setzt die aktuelle Position auf den Wert zurück, den sie beim Aufruf von mark hatte.

Das Argument für mark gibt an, wie viele Bytes Sie nach dem Aufruf von mark lesen können, bevor die Markierungsposition ungültig wird. Sobald die Markierungsposition ungültig geworden ist, können Sie nicht mehr reset aufrufen, um zu ihr zurückzukehren.

Wenn beispielsweise mark(2) in Zeile 4 verwendet worden wäre, würde beim Aufruf von reset() in Zeile 6 eine IOException ausgelöst, da die Markierungsposition ungültig geworden wäre, da wir mehr als 2 Bytes gelesen haben.

8voto

AJK Punkte 126

Gepufferte Readers/Writers/InputStreams/OutputStreams lesen und schreiben zur Optimierung in großen Blöcken in das Betriebssystem. Im Falle von Writern und Outputstreams werden die Daten im Speicher gepuffert, bis genügend Daten gesammelt sind, um einen großen Brocken zu schreiben. Im Falle von Lesern und Inputstreams wird ein großer Brocken von der Festplatte/dem Netzwerk/... in den Puffer gelesen und alle Lesevorgänge werden von diesem Puffer aus durchgeführt, bis der Puffer leer ist und ein neuer Brocken eingelesen wird.

DataInputStream ist tatsächlich bytebasiert. Die readLine-Methode ist veraltet. Intern liest sie Bytes von der Festplatte/dem Netzwerk/... Byte für Byte, bis sie eine komplette Zeile erfasst hat. Dieser Stream könnte also beschleunigt werden, indem ein BufferedInputStream als Quelle verwendet wird, so dass die Bytes für die Zeile aus dem Speicherpuffer statt direkt von der Festplatte gelesen werden.

5voto

Tendayi Mawushe Punkte 24821

Bei ungepufferter E/A wird jede Lese- oder Schreibanforderung direkt an das Betriebssystem weitergeleitet. Die gepufferten E/A-Streams von Java lesen und schreiben Daten in ihren eigenen Speicherpuffer (normalerweise ein Byte-Array). Aufrufe an das Betriebssystem erfolgen nur, wenn der Puffer leer ist (bei Lesevorgängen) oder der Puffer voll ist (bei Schreibvorgängen). Es ist manchmal eine gute Idee, den Puffer nach kritischen Punkten in Ihrer Anwendung manuell zu leeren.

Da die API-Aufrufe des Betriebssystems zu Festplattenzugriffen, Netzwerkaktivitäten und ähnlichem führen können, kann dies recht teuer werden. Die Verwendung von Puffern zur Aufteilung der nativen E/A des Betriebssystems in größere Abschnitte verbessert die Leistung oft erheblich.

2voto

Henning Punkte 15543

Gepufferte Streams schreiben oder lesen Daten in größeren Blöcken nach - nomen est omen - Pufferung . Je nach zugrunde liegendem Stream kann dies die Leistung erheblich steigern.

Von java.io.BufferedOutputStream Javadocs:

Durch die Einrichtung eines solchen Ausgabestroms, kann eine Anwendung Bytes in den zugrunde liegenden zugrunde liegenden Ausgabestrom schreiben, ohne notwendigerweise einen Aufruf an das zugrundeliegenden System für jedes Byte geschrieben wird.

0voto

Anju Singh Punkte 367

Um diese Art von Overhead zu reduzieren, implementiert die Java-Plattform gepufferte E/A-Streams. Gepufferte Eingabeströme lesen Daten aus einem Speicherbereich, der als Puffer bezeichnet wird; die native Eingabe-API wird nur aufgerufen, wenn der Puffer leer ist. Analog dazu schreiben gepufferte Ausgabeströme Daten in einen Puffer, und die native Ausgabe-API wird nur aufgerufen, wenn der Puffer voll ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X