[*nix / PHP ] Große Datei stückweise rückwärts einlesen

GeYe

Lt. Junior Grade
Registriert
Aug. 2002
Beiträge
486
Datei:
Code:
Zeile 1
Zeile 2
Zeile 3
...
Zeile 90000

Ich möchte nun möglichst stückweise die Datei rückwärts einlesen, wobei natürlich die Zeilen an sich erhalten bleiben sollen, also quasi

Code:
Zeile 90000
Zeile 89999
Zeile 89998

Das Problem ist eben, dass es zahlreiche Lösungen gibt. Nur das Problem ist, dass die Datei etwa 50 MB groß ist und trotzdem ausgelesen werden soll und später, wie bei Gästebüchern bekannt in Stücken als HTML dargestellt werden soll.

Bei PHP bin ich mir ziemlich sicher, dass es nicht geht, aber bei Unix gibt es bestimmt eine knifflige Lösung. :D
 
mit php wäre das schon möglich.
gibt ja die funktion file("dateiname").

die liest die datei in ein array, also jedes feld im array hat eine zeile.
das muss man dann nurnoch mit einer for-schleife rückwärts auslesen.

wielang das bei einer 50mb großen datei dauert kann ich dir nicht sagen. aber ich denke wenn du doch php nutzen willst, wäre eine mysqldatenbank angebrachte und vorallem schneller.
 
ja klar wäre es angebrachter, aber ich kann nicht ;-)

Die Logdatei wird von einem Programm erzeugt. Die Brick erzeugt mir Eurexc eine Logdatei für Ein und Ausgängen. Ich hab das ja schon vorgeschlagen, aber direkt am Eurexc werd ich jetzt nicht rumproggen.

Mit file kann ich es leider nicht auslesen. Das habe ich schon versucht. Alle Versuche mit PHP die 50 MB große Datei auszulesen sind gescheitert oder dauern einfach viel zu lang => Rechnerlast zu hoch => andere Anwendungen können dann nicht laufen.
 
Das Problem wird sein das du die MaxExecution Time deiner PID (deines Scriptes) erreichst bevor das Script abgearbeitet ist. Eventuell kannst du diese Zeit hochsetzen. Als andere Lösung würde mir einfallen die Datei zu teilen oder das ganze auf ne SQL DB zu legen.
 
du könntest auch die datei öffnen, mit fseek die lese position auf das letzte zeichen setzen und dann mit ner schleife solange den pointer um eins nach vorne setzten bis du /n erreicht hast(zum überprüfen einfach die chars einzeln mit fgetc einzeln anlesen). dann kannst du ne ganze zeile einlesen und der spass geht von vorne los. is zwar etwas aufwendiger aber das wird am ende warscheinlich schneller laufen, da php einige probleme hat wenn ein script zuviel ram verbraucht(es wird dann immer langsamer, war zumindest bei php4 so). ausserdem gibt es auch ein ram limit, wenn du also keinen zugriff auf die ini hast geht es mit php garnicht anders. um die maximale ausführungszeit zu umgehen könntest du immer 50 zeilen einlesen und das script dann automatisch erneut aufrufen lassen und die zeilen position per get übertragen(wenn dus um browser hast einfach header("Location: ...") auf eine redirect datei zeigen die das selbe nochmal mit dem echten script macht ;). ich glaube wenn du die selbe url in den location header machst tut der browser garnix).


EDIT: wobei das natürlich totaler schwachsinn ist. wenn man schon eh alle zeichen einseln liest dann könnte man auch nen ganzen string damit zusammen bauen und den so in die neue datei schreiben, anstatt die zeile dann nochmal extra einzulesen...
 
Zuletzt bearbeitet:
hm... gibts eine elegantere Unixshelllösung?

SQL ist nicht drin. Die Datei komplett einzulesen dauert zu lange (man brauch ja sowieso nicht die Information von den zig tausend Zeilen, sondern meistens sowieso vielleicht nur 1000 vom Schluss).

Zeichen für Zeichen einlesen ist auch Hardcore *g*. Ich vermute mal das wird auch übel langsam sein. Aber einen Test am Montag wird es mir wert sein :D
 
Du könntest ja noch eine zweite (binäre) Datei als "Index" erstellen, in die schreibst du dann (z.B. als int) für jede Zeile bei welchem Zeichen Sie anfängt und wie lange sie ist.
Um in der Indexdatei die richtige Zeile zu finden brauchst du dann nur ein fseek(f, Zeilennummer * 8), und wenn du erstmal weißt wo die Zeilen in deiner "großen" Datei sind dürften die sich auch recht schnell einlesen lassen.
 
Zurück
Oben