Datei close() nötig?



  • Der Destruktor übernimmt das Schließen. Daran ist auch nichts stilistisch schlechtes, denn dafür sind Destruktoren da.



  • Daran vielleicht nicht, aber vielleicht das die Methode / Funktion länger ist, oder eine Datei geöffnet wird und nicht wieder in der selben Funktion geschlossen wird.

    Dann weiß ein andere auf den ersten Blick einfach nicht bescheid. Aber das ist nur my humble opinion.



  • Was passiert wenn der Destructor die Datei nicht schließen kann. close() kann schließlich fehlschlagen wenn z.B die Platte voll ist. Eine Ausnahme darf der Dtor nicht werfen... Bei einem lang laufenden Programm ist das verlassen auf den Destruktor glaube ich keine gute Idee - Wenn man aber nur mal schnell was lesen will...

    Jeder wie er will. Man sollte einfach nur bedenken das Filedeskriptoren eine begrenzte Resource sind.

    mfg, KdeE



  • nach rückkehr eine funktion (und es ging ja um die funktion) wird automatisch der destruktor aufgerufen, wozu dann doppelt moppeln?

    so long



  • elise schrieb:

    nach rückkehr eine funktion (und es ging ja um die funktion) wird automatisch der destruktor aufgerufen, wozu dann doppelt moppeln?

    so long

    libstdc++ schrieb:

    template<typename CharT, typename Traits>
    void std::basic_fstream< CharT, Traits >::close ( ) [inline]

    Close the file.

    Calls std::basic_filebuf::close(). If that function fails, failbit is set in the stream's error state.

    Mache ich das erst im Destruktor kann ich das failbit nicht mehr testen (Oder sehe ich da was falsch?). IMHO nicht nötig für kleine Programme und vor allem für solche die nur lesen, wichtig finde ich es aber für Programme die schreiben und lange laufen, z.B Server.

    mfg, KdeE 🙂



  • Morgen,

    wenn die Funktion beendet ist, was willst du dann noch testen?

    mfg
    v R



  • eben.
    KdeE sieht nicht, daß es um funktionen geht.
    und das beenden dieserjenigen.

    so long

    ps: aber ich kämpf nich drum, spätestens in irgendeiner newsgroup wird man ev. zusammengestaucht 😉



  • dasding123 schrieb:

    wird automatisch gemacht aber für mich ists schlechter stil wenn dus weglässt.

    Warum sollte es schlechter Stil sein, Redundanz zu vermeiden?



  • KdeE schrieb:

    Mache ich das erst im Destruktor kann ich das failbit nicht mehr testen (Oder sehe ich da was falsch?).

    Sobald du .close() statt dem Dtor verwendest, hast du RAII nicht verstanden - und ohne RAII ist C++ ein einziger Kampf - denn da es kein finally gibt (da wir RAII haben, brauchen wir es auch nicht) fällt man in die C Zeiten zurück und das Resourcenmanagement ist viel zu aufwendig.

    Wenn du unbedingt das failbit testen willst (wozu auch immer) - dann schreibe dir einen Guard dafür, der im Dtor .close() aufruft und das failbit checkt.



  • nman schrieb:

    dasding123 schrieb:

    wird automatisch gemacht aber für mich ists schlechter stil wenn dus weglässt.

    Warum sollte es schlechter Stil sein, Redundanz zu vermeiden?

    Schlechter Stil ist auch unleserlicher Code. Und aus den paar Takten mach ich mir gar nix, höchstens der Optimizer 😉
    Dafür ist es lesbarer.

    Ist gibt nämlich auch, wer hätte es gedacht, Funktionen die nicht so aussehen

    void Foo()
    {
      // Datei öffnen
       // 5 zeilen code
    }
    

    Aber das ist eben Ansichtssache. Bei Minifunktionen lass ichs aber auch weg.



  • dasding123 schrieb:

    Schlechter Stil ist auch unleserlicher Code. Und aus den paar Takten mach ich mir gar nix, höchstens der Optimizer 😉
    Dafür ist es lesbarer.

    Ach was, dann dürfte ich ja auch nicht ifstream foo("foo.bar"); schreiben sondern nur ifstream foo; foo.open("foo.bar");
    Der Grund aus dem ich gegen ein explizites foo.close() bin ist nicht Performance; wenn Du foo.close() weglässt wird Dein Code nämlich nicht performanter. Es geht vielmehr darum dass man dank RAII den close-Aufruf ganz einfach weglassen kann; eine der schönen Seiten an modernem C++.

    Ist gibt nämlich auch, wer hätte es gedacht, Funktionen die nicht so aussehen

    void Foo()
    {
      // Datei öffnen
       // 5 zeilen code
    }
    

    Ich verstehe leider nicht, was Du mir damit sagen möchtest.



  • Ich verstehe leider nicht, was Du mir damit sagen möchtest.

    Ist doch klar. Er will dir sagen, das er gerne riesiege unhandhabbare Codemonster baut.

    @dasding123: sowas geht auch

    void foo ()
    {
       { 
          ifstream datei("pfad");
          ... // lies was aus der Datei
       }
    
       ... // weiterer Code
    }
    


  • Also wenn ich so einen Code lese, denke ich an ein Resource-Leak:

    void foo()
    {
      Class obj("foo");
      //...
      if(something_happened()) return;
      //...
      obj.close();
    }
    

    Das sieht doch so aus, als würde Class kein RAII implementieren und man hätte durch das return obj nicht ordnungsgemäß freigegeben...

    Lasse ich das obj.close(); dann kann man davon ausgehen, dass obj ordnungsgemäß im Ctor zerstört wird.



  • Dann doch lieber close() 🙂

    Mal im Ernst, der Missionierungseifer hier geht mir manchmal gewaltig auf den Senkel.



  • Helium schrieb:

    Ist doch klar. Er will dir sagen, das er gerne riesiege unhandhabbare Codemonster baut.

    Ja, nur kenne ich niemanden der das freiwillig in aller Öffentlichkeit zugeben würde. 🙂



  • Das ist immer die schönste Art, über andere herzuziehen und "Witze" zu machen.
    Ein bischen Ignoranz schadet scheinbar nie. Ja, ich programmiere nur Codemonster, inperformant und bin auch privat ein Arschloch.

    Mehr will ich nicht mehr dazu sagen. 👎



  • Ja und wie ist das jetzt wenn bei close() wirklich ein Fehler autritt wie Kde das gesagt hat? sollte man das wirklich ignorieren?



  • Wenn du unbedingt das failbit testen willst (wozu auch immer) - dann schreibe dir einen Guard dafür, der im Dtor .close() aufruft und das failbit checkt.

    Das hier ist imho der sinnvollste Ansatz.

    Ich kenne mich mit der Windows API nicht gut aus, aber auch dort kann CloseHandle() eine Ausnahme werfen (Grade bei m$ nachgeschaut). Unter Linux kann fclose folgendes machen:

    The fclose function may also fail and set errno for any of the errors
    specified for the routines close(2), write(2) or fflush(3).

    D.h. Wenn man ein modernes Betriebsystem mit Buffern und Caches verwendet kann es durchaus sein das man mehr in eine Datei schreibt als Festplattenplatz vorhanden ist (Beispiel). Diese Art von Fehler wird erst beim schließen sichtbar. Erst wenn die Datei erfolgreich geschlossen ist, ist auch garantiert das sie vollständig ist (Soweit der Programmierer das überprüfen kann).

    Aber so ein "haufen Aufwand" ist vielleicht zuviel wenn man bloß bisschen Text in irgendein Logfile knallen will oder wenn man NUR aus der Datei liest. Sprich es ist einfach Ermessenssache.

    mfg, KdeE

    ps: Ja ich verwende einen "Wächter" :p



  • Bashar schrieb:

    Mal im Ernst, der Missionierungseifer hier geht mir manchmal gewaltig auf den Senkel.

    Verstehe ich nicht, in diesem Thread wurde doch explizit gefragt ob man fstream::close selbst verwenden soll oder ob man dem Destruktor die Arbeit überlassen soll...

    dasding123 schrieb:

    Das ist immer die schönste Art, über andere herzuziehen und "Witze" zu machen.
    Ein bischen Ignoranz schadet scheinbar nie. Ja, ich programmiere nur Codemonster, inperformant und bin auch privat ein Arschloch.

    Jetzt mach mal halblang, wenn Du Dich von solchen Kleinigkeiten schon so beleidigen lässt dann weißt Du scheinbar echt nicht wie es in diesem Forum manchmal zugeht. 🙂



  • nman schrieb:

    Bashar schrieb:

    Mal im Ernst, der Missionierungseifer hier geht mir manchmal gewaltig auf den Senkel.

    Verstehe ich nicht, in diesem Thread wurde doch explizit gefragt ob man fstream::close selbst verwenden soll oder ob man dem Destruktor die Arbeit überlassen soll...

    Aber es kam in etwa die Antwort "close verwendet man nicht, niemals, und wers doch tut ist schlecht".


Anmelden zum Antworten