2013-04-28 11 views
5

Diese Frage: How to protect log from application crash? hat mich zu einem anderen geführt - was macht eigentlich std::ofstream::close()? Ich weiß, es ruft flush() und das ist eine Sache. Aber was noch? Was ist eigentlich das Schließen der Datei?Was macht std :: ofstream :: close() eigentlich?

Edit: Lassen Sie mich meine Frage umformulieren - ist alles physisch auf die eigentliche Datei getan während des Gesprächs zu close() oder ist es nur std::ofstream interne Bereinigungs Zeug?

Antwort

3

Anders als die User-Space-Puffer gespült, das heißt flush(), close(2) auf der zugrunde liegenden Datei-Descriptor bezeichnet. Es hängt vom Betriebssystem ab, was dann passiert, aber höchstwahrscheinlich passiert nichts mit dem tatsächlichen Speicher, der von der Datei belegt ist.

Was wird geschehen ist, dass der Dateieintrag, der der Datei zugeordnet ist, aus der geöffneten Dateitabelle des Prozesses entfernt wird (wenn der Dateideskriptor der letzte Verweis in diesem Prozess auf diese Datei war). I.e. Prozess-assoziierten Kernel-Speicher freigeben. Hier

1

Schließt die aktuell mit dem Objekt verknüpfte Datei und trennt sie vom Stream.

Jede ausstehende Ausgabesequenz wird in die Datei geschrieben.

Wenn der Datenstrom derzeit keiner Datei zugeordnet ist (d. H. Keine Datei wurde erfolgreich damit geöffnet), schlägt der Aufruf dieser Funktion fehl.

Die Dateizuordnung eines Streams wird durch den internen Stream-Puffer beibehalten: Intern ruft die Funktion rdbuf() -> close() auf und setzt failbit im Fehlerfall.

Beachten Sie, dass jede geöffnete Datei automatisch geschlossen wird, wenn das Ofstream-Objekt zerstört wird.

Von: http://www.cplusplus.com/reference/fstream/ofstream/close/

+0

Ich habe meine Frage umformuliert, bitte sehen Sie die Bearbeitung des ursprünglichen Beitrags. – NPS

3

ist die Spur der Anrufe von Dokumentation:


void std::basic_ofstream::close(); 

Effektiv ruft rdbuf()->close(). Tritt während des Betriebs ein Fehler auf, wird setstate(failbit) aufgerufen.


std::basic_streambuf<CharT,Traits>* std::basic_ofstream::rdbuf() const; 

Gibt den zugehörigen Strompuffer. Wenn kein Stream-Puffer zugeordnet ist, wird NULL zurückgegeben.


std::basic_streambuf tatsächlich erbt std::basic_filebuf daher:


std::basic_filebuf<CharT, Traits>* std::basic_filebuf::close(); 

Wenn ein Bereich Put existieren (zB Datei zum Schreiben geöffnet wurde), overflow(Traits::eof()) ersten Anrufe alle anstehenden Ausgabe in die Datei zu schreiben, einschließlich beliebiger Unshift-Sequenzen.

Wenn die zuletzt genannte Funktion, aus underflow(), overflow(), seekpos() und seekoff() war overflow(), dann std::codecvt::unshift() nennt, vielleicht mehrere Male, die unshift Sequenz zu bestimmen nach dem Imbued locale und schreibt diese Sequenz in Datei mit overflow(Traits::eof()).

Schließt dann die Datei wie durch Aufrufen von std::fclose, unabhängig davon, ob einer der vorhergehenden Aufrufe erfolgreich war oder fehlgeschlagen ist.

. HINWEIS:close() wird in der Regel durch den destructor von std::basic_filebuf genannt (was wiederum typischerweise durch den destructor von std::basic_fstream genannt wird


Zunächst einmal können wir sehen, dass es doesn‘ t rufen Sie eigentlich flush() direkt, wie Sie erwartet.Noch die Spülung Effekt tritt tatsächlich in der std::basic_filebuf::close() Methode.Zusätzlich können wir sehen, dass es immer noch ein bisschen manipuliert mit einer Datei, dh das Schreiben der Unshift-Sequenz passiert dann, Die Datei wird einfach geschlossen.

Achten Sie auf die HINWEIS oben: In den meisten Fällen müssen Sie nicht einmal std::basic_ofstream::close() explizit aufrufen.