Sicheres Schliessen eines geöffneten istreams/ostreams



  • Naja, ich würd stark vermuten, dass der Destruktor auch nichts anderes macht als close(). Natürlich muss der Stream beim closen nochmal geflusht werden, sonst wär jda die Datei unvollständig.



  • Eben, und wenn das Objekt zerstört ist, kannst du nicht mehr prüfen, ob flush funktioniert hat. Wenn du nur close aufrufst schon.



  • RockMe schrieb:

    Closes the file currently associated with the object, disassociating it from the stream. Any pending output sequence is written to the physical file.

    Ich würde mal sagen, dabei kann noch mehr schief gehen.

    Noch mehr als wobei? Das einem close implizit ein flush voraus geht, sollte ja wohl klar sein.



  • Tachyon schrieb:

    Noch mehr als wobei?

    Mehr als das was du schreibst.

    Tachyon schrieb:

    Ansonsten kann man tatsächlich explizit close() aufrufen und auf badbit prüfen. Das kann für close() aber eigentlich nur gesetzt werden, wenn man keine Datei geöffnet hat (wenn das Öffnen schief geht, ist badbit eh schon gesetzt).



  • Was ist falsch, oder was fehlt an der Aussage?



  • Das:

    Das ... badbit ... kann für close() aber eigentlich nur gesetzt werden, wenn man keine Datei geöffnet hat



  • RockMe schrieb:

    Das:

    Das ... badbit ... kann für close() aber eigentlich nur gesetzt werden, wenn man keine Datei geöffnet hat

    Tja, in der Theorie wäre es schön, wenn es so wäre, dass auch bei Speichermangel badbit gesetzt wird. Leider definiert des Standard das nicht. Das einzige definierte Fehlerverhalten, ist das oben von mir beschriebene.



  • Tachyon schrieb:

    Tja, in der Theorie wäre es schön, wenn es so wäre, dass auch bei Speichermangel badbit gesetzt wird. Leider definiert des Standard das nicht. Das einzige definierte Fehlerverhalten, ist das oben von mir beschriebene.

    Dann ist ja ofstream für alles sicherheitsrelevante völlig ungeeignet, wenn man nicht mal prüfen kann, ob irgendwas auf Platte geschreiben wurde.



  • RockMe schrieb:

    Dann ist ja ofstream für alles sicherheitsrelevante völlig ungeeignet, wenn man nicht mal prüfen kann, ob irgendwas auf Platte geschreiben wurde.

    Tja, nichts ist jemals einfach...



  • Wird das mit dem neuen Standard verbessert?



  • RockMe schrieb:

    Wird das mit dem neuen Standard verbessert?

    Hmm, ich glaube, ich habe mal wieder Müll erzählt, zumindest zum Teil. Auf gängigen Plattformen dürfte das intern (in std::filebuf) benutzt std::fclose einen Fehler erzeugen, wenn irgendwas schief geht (kein Platz, Datei inzwischen gelöscht, etc.).

    Allerdings ist das Verhalten implemntierungsabhängig, weil ja der Filedeskriptor aus allen möglichen Quellen kommen kann und auf allen möglichen Plattformen funktionieren ssoll, und bestimmte Fehler gar nicht auftreten können. Man kann also gar kein eindeutiges Fehlerverhalten definieren.

    Auf gängigen Plattformen sollte z.B. auch ein fstream::close() zum Setzten von badbit führen, wenn z.B. kein freier Speicher zum Schreiben des Restpuffers da ist.
    Das Problem ist eben, dass man sich nicht darauf verlassen kann. Nur das am Anfang beschriebene Verhalten ist klar definiert.



  • Dateioperationen sind ohne spezielle Hilfe vom OS nie verlässlich, egal wie der fstream arbeitet. Das Dateisystem ist eine geteilte Resource.

    Andere Anwendungen können z.B. die selbe Datei gleichzeitig öffnen (vielleicht unter Windows nicht, aber mit dem native API dann wahrscheinlich doch), dann kann es passieren dass man 10 Bytes schreibt und die Datei plötzlich 20 Bytes lang ist. Das Filehandle kann dir unterm Schreiben vom OS entzogen werden (probier mal chkdsk /F /V aus). Im Prinzip kann auch das OS zurückmelden, dass die Bytes geschrieben wurden, und dann plötzlich abrauchen ohne dass es wirklich auf der Disk steht. Nicht mal sowas wie FileExists(path) == FileExists(path) ist zwangsläufig immer true, weil es zu race conditions kommen kann.

    Ohne spezielle Hilfe und Garantien vom OS sind Dateioperationen nicht verlässlich, und es gibt meiner Meinung nach nichts, was fstream dagegen tun kann. Dafür ist es einfach zu systemfern. Das heißt aber nicht, dass es unbrauchbar, man sollte halt nur kein Datenbanksystem damit programmieren.


Anmelden zum Antworten