====== setbuf() ====== ''setbuf()'' ist in der ''[[c:lib:stdio:start|stdio]]'' definiert, die in C über ''stdio.h'', bzw in C++ über ''cstdio'' eingebunden wird. ===== Funktion ===== ''setbuf()'' gibt den IO-Buffer an, der für den ''FILE''-Stream verwendet werden soll. Wird ''[[c:lib:stddef:NULL]]'' übergeben, so wird der Stream nicht gepuffert. Gepufferte Streams werden nicht sofort auf die Festplatte geschrieben, sondern Lese- und Schreibvorgänge werden zunächst im Puffer gesammelt. Da Dateisysteme Daten in Blöcken ablegen, werden pro Schreibzugriff in der Regel 512 Bytes geschrieben. Würde ein Byte geändert, so muss der vorhandene Block gelesen, verändert und auf das Dateisystem zurückgeschrieben werden. Schreibt man nun Buchstabe für Buchstabe, bedeutet das extrem viel Aufwand, so dass zunächst in einen Puffer geschrieben wird. Wenn der Puffer voll ist, werden die gesammelten Daten an einem Stück übertragen. Wird die Datei mit ''[[fclose()]]'' geschlossen, so werden alle noch nicht geschriebenen Daten zunächst auf die Festplatte kopiert. Dies lässt sich auch künstlich durch die ''[[fflush()]]''-Anweisung auslösen, ohne die Datei zu schließen. Einige Betriebssysteme unterscheiden zwischen zeichen- und zeilenorientierten Streams. Für zeilenorientierte Streams ist die ''[[setvbuf()]]''-Funktion zu verwenden. Dateien werden automatisch mit einem Puffer ausgestattet. ''[[stdin]]'', ''[[stdout]]'' und ''[[stderr]]'' sind ohne Buffer ausgelegt, um Ausgaben sofort an die Konsole liefern zu können. ===== Signatur ===== #include void setbuf( FILE * stream, char * buffer ); **stream**: der zu konfigurierende Stream\\ **buffer**: Zeiger auf den Speicherbereich, der als Puffer dienen soll oder ''[[c:lib:stddef:NULL]]'', für ungepufferte Ausgaben \\ ===== Fehlerquellen ===== ''buffer'' muss mindestens so groß sein, wie in ''[[BUFSIZ]]'' angegeben. ''setbuf()'' sollte direkt nachdem die Datei geöffnet wurde und bevor irgendeine Ein- oder Ausgabe über den Stream gelaufen ist. Sobald Streams gepuffert werden, werden Schreibzugriffe nicht mehr sofort auf den Datenträger geschrieben, sondern zunächst im Puffer gesammelt und anschließend in einem Zug auf den Datenträger geschrieben. Wird die Datei nicht ordnungsgemäß geschlossen, zum Beispiel durch einen Programmabsturz, so werden die Daten, die zunächst im Puffer zwischengespeichert wurden nicht mehr auf den Datenträger geschrieben. Das kann bei der Suche nach dem Fehler eine falsche Spur legen, da Ausgaben, die das Programm gemacht hat, in der Datei nicht mehr auftauchen und man so den Absturz an der Stelle vermutet, an der das Programm den letzten Eintrag in die Datei gesendet hat. Gerade für Log-Files empfiehlt es sich daher, mit ''setbuf()'' den Puffer auf ''[[c:lib:stddef:NULL]]'' zu setzen und damit zu deaktivieren. Da Programme normalerweise nicht abstürzen sollten, hilft der aktivierte Cache bei korrekten Programmen Lese- und Schreibvorgänge mit wenigen Daten deutlich zu beschleunigen. ===== Beispiel ===== #include #include int main (void) { FILE *file = fopen("logfile.txt", "w+"); /* Kommentar in der nächsten Zeile entfernen, um zuverlässig Logfiles zu schreiben */ // setbuf( file, NULL ); fprintf( file, "vor Absturz" ); /* Absturz provozieren */ *((int *)0) = 4711; /* Dieser Part wird nicht mehr erreicht */ fprintf( file, "nach Absturz" ); fclose(file); return EXIT_SUCCESS; } ===== Hinweis ===== Das Beispielprogramm stürzt absichtlich ab! Es zeigt den Unterschied zwischen einer gepufferten Datei im Fall eines Absturzes und der ungepufferten Datei. Ist ''setbuf()'' auskommentiert, wird eine Datei ''logfile.txt'' angelegt, die aber nicht mehr beschrieben wird, obwohl der Text "vor Absturz" zuvor geschrieben werden sollte. Die Dateigröße ist 0. Wird ''setbuf()'' aufgerufen, so wird der Text "vor Absturz" auf die Festplatte geschrieben, bevor das Programm in seiner Berechnung fehlschlägt und abstürzt. Die Funktion ''setbuf()'' entspricht dem folgenden Aufruf der Funktion ''[[setvbuf()]]'': setvbuf( stream, buffer, buffer ? _IOFBF : _IONBF, BUFSIZ ); ===== siehe auch ===== [[c:lib:stdio:start|stdio]]: [[c:lib:stdio:fflush()]], [[c:lib:stdio:fclose()]], [[c:lib:stdio:setvbuf()]]