Was genau ist Streambuf? Wie benutze ich es?

78

Ich versuche ein bisschen mehr darüber zu lernen, wie E / A-Streams in C ++ funktionieren, und ich bin wirklich verwirrt, wann ich was verwenden soll.

Was genau ist ein streambuf?
Wann verwende ich a streambufim Vergleich zu a string, an istreamoder a vector? (Ich kenne die letzten drei bereits, aber nicht, wie sie streambufmit ihnen verglichen werden, wenn überhaupt.)

user541686
quelle
Es ist eine schlechte Abstraktion eines Stream-Puffers.
Pubby
1
@Pubby: Äh, was ist ein "Stream Buffer"? Wie unterscheidet es sich von einem Stream oder einem Puffer?
user541686
3
@moshbear: Entschuldigung, ich habe keine Ahnung, worauf sich das bezieht.
user541686
1
@Mehrdad Stroustrup Die C ++ Programmiersprache: Special Edition
Moshbear
4
Wenn Sie sich dadurch besser fühlen, arbeite ich seit 15 Jahren mit C ++ und erhalte immer noch nicht den E / A-Teil der C ++ - Bibliothek. Es gab kein einziges Projekt, bei dem ich die Möglichkeit hatte, es zu nutzen.
Nemanja Trifunovic

Antworten:

49

Stream-Puffer stellen Eingabe- oder Ausgabegeräte dar und bieten eine Low-Level-Schnittstelle für unformatierte E / A für dieses Gerät. Ströme, andererseits bieten eine höhere Ebene Wrapper um die Puffer mittels basischer unformatierte I / O - Funktionen und insbesondere über formatierten E / A - Funktionen (dh operator<<und operator>>Überlastungen). Stream-Objekte können auch die Lebensdauer eines Stream-Puffers verwalten.

Beispielsweise verfügt ein Dateistream über einen internen Dateistreampuffer. Der Stream verwaltet die Lebensdauer des Puffers und der Puffer bietet die tatsächlichen Lese- und Schreibfunktionen für eine Datei. Die Formatierungsoperatoren des Streams greifen letztendlich auf die unformatierten E / A-Funktionen des Stream-Puffers zu, sodass Sie immer nur die E / A-Funktionen des Streams verwenden müssen und die E / A-Funktionen des Puffers nicht direkt berühren müssen.

Eine andere Möglichkeit, die Unterschiede zu verstehen, besteht darin, die unterschiedlichen Verwendungszwecke von Gebietsschemaobjekten zu betrachten. Streams verwenden die Facetten, die mit Formatierungen wie numpunctund zu tun haben num_get. Sie können auch erwarten, dass die Überladungen von Streams operator<<und operator>>für benutzerdefinierte Zeit- oder Gelddatentypen die Zeit- und Geldformatierungsfacetten verwenden. Stream-Puffer verwenden jedoch die Codecvt-Facetten, um zwischen den Einheiten, die ihre Schnittstelle verwendet, und den Bytes zu konvertieren. So wird beispielsweise die Schnittstelle für basic_streambuf<char16_t>Verwendungen char16_tund damit basic_streambuf<char16_t>intern codecvt<char16_t, char, mbstate_t>standardmäßig verwendet, um die char16_tin den Puffer geschriebenen formatierten Einheiten in zu konvertierencharEinheiten, die auf das zugrunde liegende Gerät geschrieben wurden. Sie können also sehen, dass Streams hauptsächlich zum Formatieren dienen und Stream-Puffer eine Low-Level-Schnittstelle für unformatierte Ein- oder Ausgabe an Geräte bieten, die möglicherweise eine andere externe Codierung verwenden.

Sie können einen Stream-Puffer verwenden, wenn Sie nur unformatierten Zugriff auf ein E / A-Gerät wünschen. Sie können auch Stream-Puffer verwenden, wenn Sie mehrere Streams einrichten möchten, die einen Stream-Puffer gemeinsam nutzen (obwohl Sie die Lebensdauer des Puffers sorgfältig verwalten müssen). Es gibt auch spezielle Stream-Puffer, die Sie möglicherweise verwenden möchten, z. B. wbuffer_convertin C ++ 11, das als Fassade für a dient basic_streambuf<char>, damit es wie ein breiter Zeichen-Stream-Puffer aussieht. Es wird die Codecvt-Facette verwendet, mit der es erstellt wurde, anstatt die Codecvt-Facette zu verwenden, die an ein Gebietsschema angehängt ist. Normalerweise können Sie den gleichen Effekt erzielen, indem Sie einfach einen breiten Stream-Puffer verwenden, der von einem Gebietsschema mit der entsprechenden Facette durchdrungen ist.

bames53
quelle
13
Dies ist 5 Jahre zu spät, daher werde ich es nicht als Antwort veröffentlichen und diese nicht akzeptieren, sondern für alle, die auch nach dem Lesen noch durch die Terminologie verwirrt sind: streambufgilt für Rohdaten (z. B. Rohbytes, Rohints) usw.), während streamfür gekochte Daten (Text, als Text formatierte Ganzzahlen usw.) gilt. Anders ausgedrückt, streamrepräsentiert die Analyse- (oder Serialisierungs-) Ebene. Wenn Sie mit einfachen Zeichenfolgen arbeiten, können Sie beide technisch verwenden, aber die Bedeutung ist unterschiedlich: streambufBedeutet, dass die Rohdaten die Zeichenfolge selbst sein sollen, während streamdie Codierung abstrahiert wird.
user541686
@Mehrdad Darf ich fragen, was es bedeutet, wenn man sagt stream, dass die Kodierung abstrakt ist ? : D Können Sie es etwas näher erläutern oder weiteres Material bereitstellen?
Rick
3
@ Rick: Sicher. streamist verantwortlich für das Lesen und Schreiben von Objekten an a streambuf. streambufist verantwortlich für das Speichern und Wiederherstellen von Bytes (oder Zeichen / Wörtern / wie auch immer Sie sie nennen möchten) von einem Byte-Speicherort. Die Zuordnung zwischen Objekten und Bytes habe ich als "Codierung" bezeichnet. Ein Beispiel hierfür ist, dass a ein streamakzeptiert intund dann entscheidet, wie das in chars konvertiert wird , und umgekehrt - es könnte das Big-Endian-Format, das Little-Endian-Format, ein bitumgekehrtes Format, ein 7-Bit-Format verwenden. nur Format oder irgendetwas anderes. dh es abstrahiert das Speicherformat.
user541686
68

Mit Hilfe von streambufkönnen wir auf einer noch niedrigeren Ebene arbeiten . Es ermöglicht den Zugriff auf die zugrunde liegenden Puffer.

Hier einige gute Beispiele: Kopieren, Laden, Umleiten und Abschlagen mit C ++ - Streambufs und in Bezug auf den Vergleich: Dies kann hilfreich sein.

Geben Sie hier die Bildbeschreibung ein

Weitere Informationen finden Sie hier: IOstream-Bibliothek

COD3BOY
quelle
2
Ich habe überall nach etwas gesucht, das sowohl Streambufs als auch diesen Artikel erklären kann. Danke, dass du mir geholfen hast, es zu finden!
wvdschel
1
Beispiel ist immer am besten. Vielen Dank
Eigenfeld