[C]Datei im Zugriff verkleinern

Herakles

Profifragensteller
Moin!

Ich schreibe mit einem kleinen Programm munter in eine Datei, die ich zuvor mit fopen(3) geöffnet habe. Die Datei bleibt in meinem Programm ständig offen, ich führe also niemals ein fclose(3) durch. Das Programm läuft in einer Endlosschleife und soll nicht unterbrochen werden.

Mit der Zeit wird die so erstellte Datei recht groß und ich würde gern im Betrieb meines Programms die Datei "kleiner machen" - also zum Beispiel die ersten Teile wegwerfen. Es ist eine logging-Textdatei, bei der ich Teile löschen könnte, wenn sie nichts wichtiges beinhalten.

Ich will also eine Datei verändern, die gerade durch mein Programm beschrieben wird.

Geht das überhaupt? Und falls ja, wie?

Danke & Grüße
Herakles
 
Ich schreibe mit einem kleinen Programm munter in eine Datei, die ich zuvor mit fopen(3) geöffnet habe. Die Datei bleibt in meinem Programm ständig offen, ich führe also niemals ein fclose(3) durch....

Wer hat Dir sowas beigebracht?


Das Programm läuft in einer Endlosschleife und soll nicht unterbrochen werden.

Was aber kein Grund ist, etwas Struktur reinzubringen ... z.B. indem man ne function() macht und in der loop aufruft, in der die Zeilen geschrieben bzw. angehangen werden. Dort findet man dann nicht nur ein fopen() sondern auch ein fclose() ;-)

Mit der Zeit wird die so erstellte Datei recht groß und ich würde gern im Betrieb meines Programms die Datei "kleiner machen" - also zum Beispiel die ersten Teile wegwerfen. Es ist eine logging-Textdatei, bei der ich Teile löschen könnte, wenn sie nichts wichtiges beinhalten.

warum schreibst Du dann "nichtwichtige Zeilen" ueberhaupt erst in die Datei?


Ich will also eine Datei verändern, die gerade durch mein Programm beschrieben wird.
Geht das überhaupt? Und falls ja, wie?

Natuerlich geht das nicht!
wenn .. dann ueber den Weg Datei einlesen, filtern, temopaer speichern, Datei loeschen, von tmp nach Datei kopieren.

wenn es nur um das Verkleinern geht ... also die ersten und somit alten Zeilen rausschmeissen ... dann gibt es z.B. in Perl File::Tail ... und in C sieht das dann ungefaehr so aus:
http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tail.c

Gruss walter
 
Ich will also eine Datei verändern, die gerade durch mein Programm beschrieben wird.
Geht das überhaupt? Und falls ja, wie?

Geht schon, mit ftruncate(2), damit kann man aber nur "auf Länge" schneiden. Es geht leider damit nicht, sozusagen vorne etwas wegzuschneiden oder irgendwo in der Mitte.

Versuch es doch mit einer Art Ringpuffer. Nach einer gewissen Anzahl writes setzt du den Ausgabezeiger mittels lseek(2), fseek(3) oder rewind(3) wieder auf den Start der Datei und überschreibst die ältesten Zeilen.

Rob

EDIT: Geht natürlich nur von Innen, also von deinem Programm selber.
 
Zuletzt bearbeitet:
@walter: Danke für die ruppige Antwort. Es handelt sich hier allerdings um keine ausgereifte Software, sondern um ein quick-and-dirty Ding. Und ja, es wird ein fclose gemacht, allerdings nicht millionenmal in der schleife, sondern erst dann, wenn man das Programm per Signal killt. Es ging mir darum, klarzustellen, dass während ich die Datei "von außen" verkleinern will während der Filedeskriptor nach wie vor im Programm offen ist.

Danke an Euch Drei für die Hilfe! Ich habe nunmehr eine Antwort auf meine Frage erhalten.

Grüße
Herakles
 
@Herakles

Sorry .. sollte nicht "ruppig" rueberkommen ... sondern eher witzig.
Ich werde dann wohl an meinen kommunikativen Faehigkeit noch etwas arbeiten
muessen.
Also, nix fuer ungut ... war nicht ruppig gemeint...

Gruss walter
 
ich denke auch nicht dass es moeglich/vorgesehen ist.
wobei die idee natuerlich gar nicht mal schlecht waere:

ein logfile, welches maximal 2megabyte belegt und danach immer wieder ueberschrieben wird. aber das wird wohl erst bei zfs4 implementiert werden ;)
von der implementierung wuerde ich sagen: einmal die groesse speichern, einmal den anfangspointer... hmm....
ein ringbuffer.

bei aktuellen dateisystemen sehe ich das problem dass die doch darauf ausgerichtet sind dass datei eher groesser werden. dass die einen anfang und ein ende haben.
und das ende ist dann auf blockgroessen aligned.
natuerlich waere es jetzt moeglich vorne einen block als geloescht zu markieren. und die datei erst im zweiten block anfangen zu lassen.

aber das erfordert eingriffe auf os-ebene.
 
Du koenntest auch einfach logrotate von newsyslog(8) verwenden, oder spricht da etwas dagegen?
 
Fürs Logging gibt es syslog und newsyslog. Ansonsten für nen Ringbuffer kannst du einfacht die Datei anlegen und je nach gewünschter Semantik mit den passenden Flags über mmap() in deinen Adressraum einblenden.
 
Danke Jungs! Ich hatte zwar auch schon in die Richtung von syslog gedacht, werde mir das Thema aber noch einmal genauer ansehen. Wenn auch keine Umsetzung für dieses kleine Testprogramm folgen wird, so werde ich es auf jeden Fall nutzen wollen, falls aus dieser Idee, die ich da habe mit diesem Testprogramm einmal mehr werden sollte.

Demzufolge also: DANKE!

Und @walter: Nix für Ungut. Ich bin da auch immer überempfindlich. Ein kleines Sensibelchen eben :)
 
Moin!

Ich schreibe mit einem kleinen Programm munter in eine Datei, die ich zuvor mit fopen(3) geöffnet habe. Die Datei bleibt in meinem Programm ständig offen, ich führe also niemals ein fclose(3) durch. Das Programm läuft in einer Endlosschleife und soll nicht unterbrochen werden.

Mit der Zeit wird die so erstellte Datei recht groß und ich würde gern im Betrieb meines Programms die Datei "kleiner machen" - also zum Beispiel die ersten Teile wegwerfen. Es ist eine logging-Textdatei, bei der ich Teile löschen könnte, wenn sie nichts wichtiges beinhalten.

Ich will also eine Datei verändern, die gerade durch mein Programm beschrieben wird.

Geht das überhaupt? Und falls ja, wie?

Danke & Grüße
Herakles

Nun das geht zum Beispiel mit Fortran :

http://www.freebsd.org/cgi/ports.cgi?query=fortran&stype=all

-- http://de.wikipedia.org/wiki/Fortran
-- https://srv.rz.uni-bayreuth.de/lehre/fortran90/fortran.pdf
-- http://www.fortran.de/

MFG rudy
 
FORTRAN - ja, das ist lange her, dass ich das mal gelernt habe! Und für meinen Fall will ich darauf auch nicht umsatteln. Aber trotzdem: Danke für den Hinweis, rudy!
 
FORTRAN - ja, das ist lange her, dass ich das mal gelernt habe! Und für meinen Fall will ich darauf auch nicht umsatteln. Aber trotzdem: Danke für den Hinweis, rudy!

Kein Ding aber den kennste bestimmt :D

Echte Programmierer verwenden PASCAL nicht
(oder auch "Echte Männer essen keine Quiche)

http://www.bruder-franziskus.de/satire/it0.htm

Auszug
" Hier sind einige Tips, um Echte Programmierer außerhalb der Computer-Säle zu erkennen.
Auf einer Party sind Echte Programmierer die, die sich in einer Ecke über Betriebssystemsicherheit und wie man drum herum kommt unterhalten.
Bei einem Football-Spiel ist der Echte Programmierer der, der die Spiele mit seiner Simulation auf Endlospapier vergleicht.
Am Strand ist der Echte Programmierer der, der Flußdiagramme in den Sand zeichnet.
Ein Echter Programmierer geht in die Disco, um sich die Light-Show anzuschauen
Auf einer Beerdigung ist der Echte Programmierer der, der sagt 'Armer George. Und er hätte das Sortierprogramm fast fertig, vor dem Herzinfarkt.'
In einem Lebensmittel-Laden ist der Echte Programmierer der, der darauf besteht, die Büchsen selbst über den Laser-Abtaster zu schieben, weil er sonst keinem traut."

Mach's gut rudy :)
 
@rudy: Wenn ich mich darin nun an manchen Stellen wiederfinde, dann muss mir das Angst machen, oder? :zitter:
 
Was hindert dich daran einfach periodische checks zu machen, ob die Datei zu groß ist und dann ggf. die Datei umzukopieren/ einen Teil wegzuwerfen?

Am ehesten würde es (ohne zu kopieren) wohl noch mit memory mapped files gehen (mmap). Ob sich das konkret dann so realisieren laesst wie du dir vorstellst, weiss ich jedoch nicht. Mit dem 'normalen' C Ansatz mit fopen/fclose sicherlich jedoch nicht.
 
Danke, kex. Ich denke, ich belasse es erstmal so wie es ist, da es eh derzeit noch im Versuchsstadium ist und ich da das Programm einfach immer mal wieder anhalten kann und die Files dann mit neuen überschreibe. Sollte ich das Programm dann aber doch noch weiterentwickeln, dann setze ich mal ein wenig Zeit in die syslog-Geschichte rein, ich habe den Eindruck, dass das das macht was ich will und den vergleichbar geringsten Aufwand darstellt.

Ich werde hier posten, falls ich irgendwann eine adäquate Lösung realisiert haben sollte.

Grüße
Herakles
 
Zurück
Oben