Datei wirklich schreiben.



  • Hallo Leute,

    ich möchte aus meinem C-Programm gerne ein Logfile schreiben. Ist ja kein Problem, nur muss ich sicher sein, dass die Datei wirklich sofort geschrieben wird. Es ist ein mobiles Device, da kann man jederzeit den Stecker ziehen.

    Also im Moment öffne und schließe ich die Datei für jede einzelne Zeile im Logfile. Aber wird sie deswegen auch wirklich gleich richtig geschrieben oder kommt das erstmal in einen Puffer? Falls ja, wie kann ich ein Schreiben erzwingen.

    Mal angenommen, die Datei würde nicht geschrieben und der Strom ist weg, fehlt dann nur die letzte Zeile oder kann dabei auch die ganze Datei flöten gehen?

    Danke,

    Günther





  • Datei-Ein/Ausgabe arbeitet normalerweise über einen Zwischenpuffer, um Zeit zu sparen (die IO-Funktionen füllen den Puffer, und wenn er voll ist, wird alles am Stück auf Festplatte weitergereicht). Du kannst aber mit fflush(datei); (C-Version) bzw. datei.flush(); oder datei<<flush; (C++-Version) erzwingen, daß der Puffer SOFORT auf Platte geschrieben wird.

    Und um dir Schreibarbeit zu sparen, kannst du mit setvbuf(datei,0,_IONBF,0); bzw. datei.rdbuf()->setbuf(0,0); die Zwischenpufferung komplett ausschalten.



  • Danke erstmal für eure Hilfe. Das hilft mir weiter.

    CStoll schrieb:

    Und um dir Schreibarbeit zu sparen, kannst du mit setvbuf(datei,0,_IONBF,0);

    Wieso spare denn da Schreibarbeit? "datei" bekomme ich doch erst, wenn die Datei geöffnet wurde, was ich ja für jeden Schreibvorgang extra mache. Oder ist das dann nicht mehr nötig? Würde das Zeit sparen, wenn die Datei offenbleibt? Würde das die Hardware (SD-Karte) schonen?

    Danke euch.

    Günther



  • Mit setvbuf(datei,0,_IONBF,0); sagst du, dass der den Buffer fürs schreiben auf 0 setzen soll (also deaktivieren). Dann sparst du dir das aufrufen von fflush nach jeder Schreiboperation. Es spart dir also Programmier-Schreibarbeit, nicht dem Computer Datei-Schreibarbeit 😉

    Aber ich glaube, das du nicht um Unix-Dateien und fsync rumkommst, da hinter dem FILE-Zeugs ja ein Unix-FD steckt, was im Kernel noch mal buffert.



  • rüdiger schrieb:

    Mit setvbuf(datei,0,_IONBF,0); sagst du, dass der den Buffer fürs schreiben auf 0 setzen soll (also deaktivieren). Dann sparst du dir das aufrufen von fflush nach jeder Schreiboperation.

    Ich glaube, du hast mich nicht richtig verstanden. Ich öffne die Datei für jeden einzelnen Schreibvorgang. Ob ich dann fflush() oder setvbuf() benutze sollte an meiner eigenen Schreibarbeit nichts ändern.

    rüdiger schrieb:

    Aber ich glaube, das du nicht um Unix-Dateien und fsync rumkommst, da hinter dem FILE-Zeugs ja ein Unix-FD steckt, was im Kernel noch mal buffert.

    ??? Das versteh ich nicht. Schreibt der das nun gleich mit fflush() oder nicht?

    Günther



  • Guenther schrieb:

    rüdiger schrieb:

    Mit setvbuf(datei,0,_IONBF,0); sagst du, dass der den Buffer fürs schreiben auf 0 setzen soll (also deaktivieren). Dann sparst du dir das aufrufen von fflush nach jeder Schreiboperation.

    Ich glaube, du hast mich nicht richtig verstanden. Ich öffne die Datei für jeden einzelnen Schreibvorgang. Ob ich dann fflush() oder setvbuf() benutze sollte an meiner eigenen Schreibarbeit nichts ändern.

    Warum machst du denn so etwas? Naja, dann brauchst du auch kein fflush. Das schließen der Datei sollte schon flushen.

    rüdiger schrieb:

    Aber ich glaube, das du nicht um Unix-Dateien und fsync rumkommst, da hinter dem FILE-Zeugs ja ein Unix-FD steckt, was im Kernel noch mal buffert.

    ??? Das versteh ich nicht. Schreibt der das nun gleich mit fflush() oder nicht?[/quote]

    Was er genau bei fflush macht weiß ich nicht. Aber ich denke mal, das er es dann aus dem FILE-Buffer an den Kernel-Buffer weiter reicht und wann der schreibt ist dann wieder eine andere Sache (die du mit fsync kontrollieren kannst).



  • Guenther schrieb:

    Würde das die Hardware (SD-Karte) schonen?

    Je nach Karte gibt eine SD Karte nach 10.000 - 100.000 Schreibvorgängen ihren Geist auf. Ich halte das nicht für eine kluge Idee, den Zwischenspeicher auszuschalten. Ich würde dir ehr raten, den noch zu vergrößern und wenn möglich das /tmp Verzeichnis in den RAM zu mounten...


Anmelden zum Antworten