Schließen einer geöffmeten Datei in C

yxy

Lieutenant
Registriert
Juli 2014
Beiträge
570
Hallo,
in C kann ich ja eine Datei öffnen mit fopen("...."...).
Nachdem ich die Datei nicht mehr brauche ist es ja normal üblich diese mit fclose(...) wieder zu schließen.

Nun gilt aber für lokale Variablen: Werden gelöscht, wenn Funktion beendet wird.
Gilt das für das lokale öffnen einer Datei auch?
Also wenn ich in einer Funktion eine Datei öffne und die Fkt. dann wieder beende, wird dann der "Pointerpfad" wieder gelöscht? Wenn das so wäre, bräuchte man ja kein fclose, oder?
 
Nein, die Datei ist immer noch offen. Nur die Variable in der der Dateihandle gespeichert ist, die ist weg. Die Datei ist fürs Betriebssystem immer noch offen. Sobald dein Programm geschlossen wird, wird die Datei auch automatisch geschlossen.
 
Theoretisch ja. Ist aber nicht so :) Nicht einmal beim Beenden des Programms werden geöffnete Dateien automatisch geschlossen, außer das Betriebssystem räumt hinterher auf (was in der Regel der Fall ist). Trotzdem würde ich Dateien immer selbst zeitnah schließen.

Der Grund dafür ist, dass es kein "lokales Öffnen" von Dateien gibt. Nicht nur, dass der Speicherbereich, in dem das FILE-Objekt abgelegt wird, auf dem nicht-lokalen Heap liegt (was du daran sehen kannst, dass fopen() den Rückgabewert FILE* hat, also einen Zeiger zurückliefert), sondern beim Öffnen wird ein System Call ans Betriebssystem (genauer: an den Dateisystemtreiber) abgesetzt, der die Datei dann bei sich als geöffnet markiert und einen Dateideskriptor (aka File-Handle) darauf zurückgibt. Bei fclose() wird dieses Handle dann wieder freigegeben. Die Anzahl der verfügbaren Deskriptoren ist aber begrenzt - wenn man nicht aufpasst, ist es durchaus möglich, dass das Betriebssystem sich irgendwann weigert, weitere Dateien zu öffnen, und zwar für _alle_ Programme im System :D
 
Nicht einmal beim Beenden des Programms werden geöffnete Dateien automatisch geschlossen, außer das Betriebssystem räumt hinterher auf (was in der Regel der Fall ist).

Das ist eigentlich IMMER der Fall eben weil die handles eine finite systemweite Ressource sind und jeder handle eine gewisse Menge Speicher braucht. Von filelocks und Zugriffsprobleme gar nicht zu reden: ich erstelle eine Datei mit Editor und beende den Editor. Dann versuche ich die Datei zu verschieben aber es geht nicht weil weder der Editor noch das OS den handle schließen: Chaos.
 
Einmal das, andererseits muss das OS auch dafür Sorge tragen, dass das System noch benutzbar ist, wenn mal ein Programm aus irgendwelchen Gründen abstürzt. :freak:

yxy schrieb:
Nun gilt aber für lokale Variablen: Werden gelöscht, wenn Funktion beendet wird.
Gilt das für das lokale öffnen einer Datei auch?
Direkt in C nicht, wie es die anderen schon gesagt haben, aber was du beschreibst, ist mehr oder weniger das RAII-Prinzip - in C++ könntest du eine Klasse schreiben, die im Konstruktor eine Datei öffnet und im Destruktor automatisch schließt, wenn die Variable "gelöscht" wird. In C musst du das von Hand erledigen (was es auch sehr viel schwieriger macht, in C wirklich zuverlässige Software zu schreiben).
 
Viele C Funktionen sind auch nur Erleichterungen um System Calls abzusetzen.
C schleift mit fopen() nur so einen System Call zum OS durch und bekommt von dem die Antwort.

Kannst ja mal probieren eine Datei zu öffnen indem du System Calls direkt aus C heraus absetzt.
Code:
www.tutorialspoint.com/unix_system_calls/open.htm
 
Zuletzt bearbeitet:
Vielleicht sollte man im Kopf haben, dass Funktionen wie fopen() den globalen Stand des Programms verändern. Solche Änderungen bleiben nach Return einer Funktion erhalten.
Nur Aktionen, deren Wirkungsbereich vollständig auf die Funktion, in der sie durchgeführt werden, beschränkt sind, können danach als erledigt angesehen werden.
Welche Aktionen globale Nebenwirkungen haben, ist unter Umständen nicht sofort klar. Dinge wie putc() haben zum Beispiel globale Nebenwirkungen. Denn der ausgegebene
Buchstabe bleibt nach Return der Funktion erhalten.

Das Beispiel mit putc() sollte auch zeigen, dass Nebenwirkungen nicht unbedingt problematisch sein müssen.

Es gibt Programmiersprachen, die Nebenwirkungen so weit wie möglich ausschließen und es ist viel einfacher mit ihnen zuverlässige Programme zu schreiben. Jemand hat hier
(vermutlich als heimlichen Witz für Eingeweihte) C++ eingeworfen, aber diese Sprache gehört offensichtlich nicht dazu. Programmiersprachen, die Nebenwirkungen vermeiden
wären beispielsweise als beliebteste Haskell, sowie meinen persönlichen Favoriten Lisp (bei dem Nebenwirkungen zwar möglich sind, aber explizit ausgewiesen werden müssen
und man auch ohne Nebenwirkungen sehr weit kommt).

Zu Lisp habe ich Links in der Signatur. Es ist heutzutage keine weit verbreitete Sprache mehr, aber das Ansehen der verlinkten Vorlesungen oder Lesen des Buches ist meiner
Meinung nach selbst für erfahrene Programmierer in vielen Fällen ein augenöffnendes Erlebnis.

mysicp.jpg
 
Zuletzt bearbeitet:
Zurück
Oben