In diesem Abschnitt wird die Verwendung der Klasse filebuf beschrieben. #include <iostream.h> typedef long streamoff, streampos; class ios public: bin, tabexp}; // sowie viele weitere Klassenelemente, siehe ios ... }; #include <fstream.h> class filebuf : public streambuf static const int openprot; /* Standardschutzmodus für Öffnen*/ filebuf();
}; | |||||
filebuf ist ein Spezialfall der Klasse streambuf, wobei Dateien als Quelle oder Ziel für die Zeichenübertragung eingesetzt werden. Zeichen werden durch Schreiben in dieDatei "aufgebraucht" und durch Lesen aus der Datei "erzeugt". Wenn das Positionierenin einer Datei möglich ist, kann auch in dem filebuf-Objekt positioniert werden. Wenndie Datei das Lesen und Schreiben erlaubt, ermöglicht die Klasse filebuf sowohl dasSpeichern als auch die Entnahme von Zeichen. Zwischen Schreib- und Lesevorgängenist kein besonderer Aufruf erforderlich (im Gegensatz zu stdio). Ein filebuf-Objekt, dasmit einem Dateideskriptor verknüpft ist, wird als geöffnet bezeichnet. Dateien werden im BS2000 ohne Angabe eines Schutzmodus verwendet. Der Reservierungsbereich (oder Puffer, siehe sbufpub und sbufprot) wird automatischzugewiesen, wenn mit einem Konstruktor oder beim Aufruf von setbuf() keine expliziteAngabe erfolgt. filebuf-Objekte können in einen nicht gepufferten Modus versetzt werden, indem an den Konstruktor oder setbuf() bestimmte Argumente übergeben werden.In diesem Fall wird bei jedem Lese- oder Schreibvorgang jedes Zeichen gleich an dasC-Laufzeitsystem durchgereicht. Dabei ist die nicht gepufferte Ein-/Ausgabe langsamerals die gepufferte. Die Zeiger get und put sind - für den Reservierungsbereich - miteinander verknüpft und verhalten sich wie ein einziger Zeiger. Die folgenden Beschreibungenbeziehen sich daher auf den einen kombinierten Zeiger. Für die folgenden Beschreibungen wird angenommen, daß
Konstruktorenfilebuf() Ein anfänglich geschlossenes filebuf-Objekt wird angelegt. filebuf(int d) Ein filebuf-Objekt, das mit dem Dateideskriptor d verknüpft ist, wird angelegt. filebuf(int d, char * p, int len) Ein mit dem Dateideskriptor d verknüpftes filebuf-Objekt wird angelegt. Das Objektist für die Verwendung des Reservierungsbereichs - beginnend bei p mit einer Längevon len byte - initialisiert. Wenn p gleich NULL oder wenn len kleiner oder gleich 0 ist, weist das filebuf-Objekt keine Pufferung auf. Elementfunktionen (nicht virtuell)filebuf * pfb=f.attach(int d) f wird mit dem geöffneten Dateideskriptor d verknüpft. Die Funktion attach() liefertüblicherweise &f; der Wert 0 wird zurückgegeben, wenn f bereits geöffnet ist. filebuf * pfb=f.close() Auf die Ausgabe wartende Daten werden geschrieben, der Puffer gelöscht, der Dateideskriptor geschlossen und die Verknüpfung mit f gelöst. Sofern kein Fehler auftritt,wird der Fehlerstatus von f gelöscht. Die Funktion close() liefert &f, wenn keine Fehler auftreten. Anderenfalls wird der Wert 0 zurückgegeben. Auch beim Auftreten vonFehlern hinterläßt die Funktion close() den Dateideskriptor und f in geschlossenemZustand. int i=f.fd() Es wird der Dateideskriptor i geliefert, mit dem f verknüpft ist. Wenn f geschlossenist, liefert fd() den Wert EOF. int i=f.is_open() Ein Wert ungleich 0 wird geliefert, wenn f mit einem Dateideskriptor verknüpft ist.Anderenfalls wird der Wert 0 geliefert. filebuf * pfb=f.open(char * name, int mode, int prot) Die Datei name wird geöffnet und mit f verknüpft. Wenn die Datei noch nicht existiert,wird versucht, sie anzulegen, sofern in mode nicht ios::nocreate bzw. ios::in angegeben ist. Virtuelle Elementfunktionenint i=f.overflow(int c) Die Beschreibung der prinzipiellen Funktionsweise finden Sie im Abschnitt sbufprot(streambuf::overflow()). streampos sp=f.seekoff(streamoff off, ios::seek_dir dir, int mode) Der Zeiger get/put wird entsprechend den Angaben in off und dir verschoben. Die Operation kann fehlschlagen, wenn die mit f verknüpfte Datei kein Positionieren unterstützt oder wenn die versuchte Verschiebung aus anderen Gründen ungültig ist (beispielsweise durch die Suche einer Position, die vor dem Dateibeginn liegt). off wird als Zählerwert interpretiert, der relativ zu der durch dir spezifizierten Position in derDatei liegt. Eine weitergehende Beschreibung finden Sie im Abschnitt zu sbufpub . streambuf * psb=f.setbuf(char * ptr, int len) Der Reservierungsbereich wird, beginnend bei ptr, auf len byte gesetzt. f ist nichtgepuffert, wenn ptr gleich NULL oder len kleiner oder gleich 0 ist. Die Funktion setbuf() liefert üblicherweise &f. Wenn f bereits geöffnet ist und ein Puffer zugewiesen wurde, wird am Reservierungsbereich oder im Pufferungsstatus keine Änderungvorgenommen, und setbuf() liefert den Wert 0. int i=f.sync() Es wird versucht, den Status des Zeigers get/put von f mit dem Status der Datei f.fd() zu synchronisieren. Dies bedeutet, daß Zeichen in die Datei geschrieben werden, wenn diese in einem Puffer für die Ausgabe vorliegen, oder eine Repositionierung (seek) in der Datei versucht wird, wenn Zeichen gelesen wurden und die Eingabe gepuffert ist. Die Funktion sync() liefert üblicherweise den Wert 0. Wenn eineSynchronisation nicht möglich ist, wird der Wert EOF geliefert. sync() gewährleistet nicht, daß das "Leeren des Puffers" auf Diskette/Platte erfolgt. Hinweis Manchmal müssen Zeichen in einem Vorgang geschrieben werden. In diesem Fall sollte das Programm die Funktion setbuf() (oder einen Konstruktor) verwenden, damit der Reservierungsbereich groß genug ist, um alle zu schreibenden Zeichen aufzunehmen. Dann kann anschließend sync() aufgerufen werden, die Zeichen werden gespeichert, und es erfolgt ein erneuter Aufruf von sync(). int i=f.underflow(); Die Beschreibung der prinzipiellen Funktionsweise finden Sie im Abschnitt sbufprot (streambuf::underflow()). | |||||
BEISPIEL | Das folgende Programm versucht, dem Dateideskriptor 1 (entspricht cout) eine Variable des Typs filebuf zuzuordnen. Anschließend wird eine Meldung ausgegeben, die den Erfolg oder Mißerfolg von attach() anzeigt: #include <iostream.h> #include <fstream.h> #include <stdlib.h> int main() { filebuf b; /* Konstruktor ohne Parameter wird aufgerufen */ if (b.attach(1)) { static char str[] = "filebuf b wurde mit Dateideskriptor 1 verknuepft\n"; b.sputn(str, sizeof(str)-1); } else { cerr << "filebuf kann nicht mit Dateideskriptor 1 verknuepft werden\n"; exit(1); /* Rückgabe bei Fehler */ } return 0; } Das Ergebnis der Programmausführung ist: filebuf b wurde mit Dateideskriptor 1 verknuepft % CCM0998 Verbrauchte CPU-Zeit: 0.0003 Sekunden | ||||
BESONDERHEITEN | |||||
Die Funktion attach() und die Konstruktoren sollten prüfen, ob der übergebene Dateideskriptor geöffnet ist. Unteilbare Lesevorgänge (atomic) können nicht erzwungen werden. | |||||
SIEHE AUCH | |||||
lseek() im C-Laufzeitsystem |