Seite 1 von 1

GZ streamen

Verfasst: 18. November 2009 10:35
von AuE
Hi,

kennt jemand von euch eine lib zum *.gz files streamen?

Ich hatte mir ja zunächst die QtIOCompressor angeschaut, allerdings ist diese nicht sequential-also seeken geht nicht
QtIOCompressor is a sequential device, which means that it does not support seeks or random access
Das ist schlecht da ich ja vor/zurücklesen möchte ohne das File auszupacken. Sprich ich will 10 Zeilen lesen (das ist kein Problem)
Aber um nach wieder zurückzugehen müsste ich ja streamen.
Also fällt der QtIOCompressor leider raus.

Kennt jmd. von euch eine gute alternative?

Verfasst: 18. November 2009 10:45
von RHBaum
Ich mach wenig auf linux .... unter windows verwenden wir die zlib.

Aber du wirst nen prinzipielles Problem haben. Aus gepackten Stroemen kann man meist nur vorwaerts lesen, nicht zurueck.
Weiterhin kannst du nicht an bestimmte stellen springen.
Iss auch irgendwie logisch.

Wennn man sowas braeucht, kannst aber auch ueber temp files gehen.
Also auspacken bis wohin du es brauchst, und den erhaltenen stream verarbeiten, und gleich in ein unkomprimiertes tempfile mit wegschreiben (kostet ned so viel an performance). musst im stream irgendwo zurueck, dann auf das tempfile schauen. Musst vor, weiter entpacken halt.

Ciao ....

Verfasst: 18. November 2009 11:08
von AuE
Ja mhhhh wenn ichj ne 10GB Log File vor mir habe möchte der User aber schon vorwärtsgehen (scrollbar)

Das heisst ich muss beim open sowieso einmal in ner runnable das ges File streamen um die Zeilenanzahl zu bekommen ( is das sinnlos )

Jmd hat mir gesagt das es da für's gunzip da ne Lib geben soll die RA fähig ist (also dann auch sequential)

Verfasst: 18. November 2009 13:53
von RHBaum
Kann schon sein, das ne lib dir da bissi mehr komfort zur verfuegung stellt.

Aber prinzipiell kannst du nie sagen, wo genau Ne bestimmte zeile liegt in nem zip, bevor das entpackt hasst.

prinzipiell funktioniert son algorythmus meist blockweisse. wenn die bloecke richtig "indizierst", kannst schon was bauen, das du ne verknuepfung zwischen index und zeilennummer hasst ....
Muss der user das mit nem standard entpacker selber entpacken koennen so das er die logdatei im txt format bekommt ?

libs, die dir wahlfreien zugriff auf die unkomprimierten daten liefern, packen das zeugs im hintergrund meist mehr oder weniger intelligent aus ....

10GByte klingt scho heftig. Ich hab mal sowas gebaut das er die daten ned in textform sondern in nem propertieren binaeren format abgedrueckt hat, und die ganzen "Texte" irgendwo als Schablonen gespeichert waren. Mit hilfe dieser und nem kommandozeilenprogramm, kommte man sich die logdatei dann im textformat, wie man es gewohnt war, erzeugen. das binaerding war dann teilweisse 1/100 gross, und man konnt trotzdem quasi meldungsweisse (1 Meldung = 1 Zeile) durchswitchen.
Der vorteil war das ich maechtig an io performance gespart hab .... (hab da auch bei ner Messung innerhalb von 10Min 1 Gbyte logs erzeugt, da wurde die Festplatte ganz schnell der engpass) ....

Ciao ...

Verfasst: 18. November 2009 14:37
von AuE
Bin immernoch auf derSuche. Dein Vorschlag scheint mir das intelligenteste zu sein.

Nee genau weiß ich das sicher nicht-das geht nur ungefähr. Und muss bei gz logfiles (es geht um rotated logs) blockweise erfolgen.

Also txt-Logs kann bin ich ca so gut wie less. Du merkst nicht das du ne 5GB Txt File vor di hast. Da sind streams was feines!

Der User soll das nicht machen müssen. Einfach via Filteroptionen (letztes Schreibdatum, Erstellungsdatum) weisen darauf hin dsa in dem File (gz) etwas sein könnte.


Es geht mir nicht darum Sachen zu schreiben-das ist alles read only...

Verfasst: 18. November 2009 17:28
von RHBaum
Also du schreibst ned, sondern wertest die nur aus ?

und 10GByte trotz logrotation ? wer macht sowas ? ^^
kannst das system ned konfigurieren, das es eher 20-50 Mbyte haeppchen schreibt ?
Also txt-Logs kann bin ich ca so gut wie less. Du merkst nicht das du ne 5GB Txt File vor di hast. Da sind streams was feines!
bei dateien von der Groesse und bei nem aktuellen prozessor Sind die IO operationen meist das bremsende.
"alle daten irgendwo durchstreamen" bei einem gescheiten compressor kann das sogar schneller sein, als wenn die unkomprimiert von der platte liest.

Wie gesagt problem ist nur die positionierung, die nimmer hasst. Man kann ned mehr einfach 4Gbyte ueberspringen und dann anfangen zu lesen, sondern muss wahrscheinlich alles von vorn lesen.

Weiss ned obs Komprimierer gibt, die mittendrinn anfangen koennen, wahrscheinlich kann es gehen, -... oder du weisst nie ab welcher posi er da rausholt und wieviel ....
DU kannst nur schaetzen .... den kompressionsgrad und wieviel pro zeile steht im schnitt, und dann grob ausrechen, mit viel puffer vor und nachher um sicherzugehen ... und dann hoffen das dein gesuchtes zeugs drinne iss ...

Ciao ...

Verfasst: 19. November 2009 08:57
von AuE
Ja, reine Ansicht.

Das Ding ist das selbst wenns nur 100MB sind das es ewig brauchen würde via readline Zeilen auszulesen und diese dann in ListWidgetItems zu packen (auch wenn ich nicht alles lreinpacke.... im schlechtesten Fall will ich die letzten 10Einträge....dann müsste ich alles mit readline lesen und das würde ohne ende kosten!

Also mir wurde gesagt das es angeblich komprimierer geben soll (weiss aber nicht was das für eine lib sein soll)

Hab grad den QIoCompressor getestet....komisch aber nen seek() gibt mir da true zurück aber seeked nicht (readline liefert immer erste zeile);

Verfasst: 19. November 2009 11:01
von AuE
Also, ich hab jetz noch mal die ZLIB angeschaut. Die kann seeken... Aber nur für die Stelle im unkomprimierten Zustand (und es ist beim Lesen sehr langsam)

Toll - woher soll ich bitte die entpackte Größe bekommen?
Weder zLib noch QIQCompressor stellen dafür was zur Verfügung...

Also doch auspacken-das ist ja sinnlos!

Verfasst: 19. November 2009 11:28
von Christian81
Das ist nunmal so bei einem Stream-Compressor... :roll:

Verfasst: 19. November 2009 12:29
von RHBaum
Das ist nunmal so bei einem Stream-Compressor
Ich versuchs Ihm ja schonend beizubringen :-)
Also doch auspacken-das ist ja sinnlos!
es gibt scho mittel, das bissi "erträglicher" zu machen, aber drumherumkommen wirst du sicher ned ganz.

das erste waer. ich wuerd das "entpacken" im hintergrund in nen eignenen Thread legen, dann funzt schon mal die oberflaeche weiter waehrend er entpackt.
witerhin entpackt einen streamkompressor sequentiell, das heisst mit den richtigen methoden kann man den anfang der datei schon lesen, waehrend der andere thread am ende der datei noch fleissig entpackt, aka anhaengt ^^

Das ganze iss aber die hohe schule von Threading, und FileIO ... kann sein das man da teilweisse zu anderen mitteln greifen muss als die Qt bietet.

Kann die QT eigentlich manuell Teilbereiche einer datei locken ???
Das Ding ist das selbst wenns nur 100MB sind das es ewig brauchen würde via readline Zeilen auszulesen und diese dann in ListWidgetItems zu packen (auch wenn ich nicht alles lreinpacke.... im schlechtesten Fall will ich die letzten 10Einträge....dann müsste ich alles mit readline lesen und das würde ohne ende kosten!
selbst wenn das ding ungepackt mit 1 GB vorliegt, wuerde mit der Methode der user am Bildschirm einschlafen ...
ich wuerd die datei beim entpacken gleich indizieren, d.h. z.B. fuer jeden Zeilenanfang die binaere startposition im File merken. Das wahrscheinlich in ein temporaeres index file schreiben ....
und dein Model darauf aufbauen ....

Ciao ....

Verfasst: 19. November 2009 12:36
von AuE
So hab jetzt mal mit zlib versucht mir die endpos zu bestimmen ....

Code: Alles auswählen

 z_off_t offset = 0;

    QTime myTime;
    myTime.start();
    while (gzseek(file, offset,SEEK_SET ) != -1)
    {
	offset++;
    }
    qDebug() << "Getting the total bytes took: "<<  myTime.elapsed() << "ms";
Getting the total bytes took: 331503 ms
Also 5min 31sek für 70,5MB gzip File (ungepackt 5,02GB)

Geht doch ;-)


Hab grade gesehen das die BOOST da noch etwas hat....

Verfasst: 19. November 2009 12:57
von RHBaum
So hab jetzt mal mit zlib versucht mir die endpos zu bestimmen ....
wobei er dir definitiv den ganzen komprimierten stream entpackt hat ^^
Also 5min 31sek für 70,5MB gzip File (ungepackt 5,02GB)
gute kompressionsrate :-) aber trotzdem ned wahnsinnig schnell, eher normal ^^

Aber deine anwendung will ja ned nur die wahre groesse des gepackten logs ermitteln ... ich wuerd auf das seek verzichten und stattdessen gleich das file komplett auspacken und temp wegschreiben.
wenn das gut hinbekommst, wird das ned wesentlich mehr zeit brauchen ...

Ciao ...

Verfasst: 19. November 2009 14:23
von AuE
Naja..... wenn man via scrollbar an die stellen will muss ich seeken-sonst muss ich 5GB im Speicher haben.... ausserdem weiß ich nicht wie es mit vorhandenen freien Speicher aussieht ...

Ich muss echt zugeben das ich noch nie so lang an nen logviewer gesessen habe ;-)

So jetzt wird die boost getestet....mal sehen was die bringt-ich halt euch auf dem Laufenden! :D

Verfasst: 19. November 2009 15:26
von RHBaum
Naja..... wenn man via scrollbar an die stellen will muss ich seeken-sonst muss ich 5GB im Speicher haben
neeee, du entzippst ja ned direkt in den speicher, oder doch ??? ^^
Deine Rangehensweisse iss bissi .... naja naiv.

du musst die datei zu ende auspacken, aum das ende zu sehen. Das schlimme daran iss, das der User wahrscheinlich zuerst das ende sehen will.
Leider verpackst du die dateien ned, sonnst koenntest es umdrehen ^^

wie gesagt ich wuerd dir "highly" empfehlen dich mit den models und mit threads und mit IO Operationen und deren grundlagen zu beschaeftigen.

Das maximalste IMHO was du aus deiner Anwendung bei deinen gegegebenheiten durchbekommst, iss:
- der User klickt aufn Logfile.
- Datei wird im hintergrund entzippt
- optional bekommt der user ne progressanzeige zu sehen
- parallel dazu liesst du scho die ersten eintraege
- zeigst dem user die eintraege an ....
- schiebst immer mehr eintraege in deinen view .... der user hat den eindruck das "der view sich fuellt"
- der ganze spuck in der zeit vorbei ist, wo du normal auch die datei selber entzippen wuerdest. also bei deinen 5GB die 5 min ....
- und dem user fliegt dabei nich sein Arbeitsspeicher um die Ohren.

Dazu musst aber schon ziemlich tief in die Materie einsteigen. Ob sich die User mit weniger zufriedengeben ... keine Ahnung, aber mehr werden sie ohne weiteres ned bekommen, ohne das Du einfluss auf das abgespeicherte logfile nehmen muesstest.

Bei anderen dateien wuerde ich vielleicht empfehlen, zu der komprimierten datei nen index zu erstellen, welcher block welche zeilennummern enthaelt und das zur navigation verwenden. aber das wird sehr komplex und lohnt nur, wenn du die gleichen unveraenderten dateien oefters aufmachen musst. ergo ned in deinem fall.

Bevor ich mich mit der komprimierung beschaeftigen wuerd:
wuerd ich erst mal das 5GB File nehmen als input.
und dazu nen view bauen, wo der User per scrollbalken auf ungefaehre positionen springen kann .... ohne das wenn der den scrollbalken bewegt, gleich erst mal die App 2 min steht .... sondern das quasi sofort passiert, und der verwendete arbeitsspeicher auch nicht mal fix um 2GB ansteigt. Und das ganze natuerlich noch so, das deine eigene Funktionalitaet immer noch einhaengen kannst, also kein fertigen filewiever einbaust den ned mehr beeinflussen kannst ^^
Und glaub mir, das ist schon ne sehr Fortgeschrittene Thematik und alles andere als trivial.

Nur mal nen rechenbeispiel :
deine 5 GiByte
=1024*1024*1024 * 5 Byte
ne Zeile hat wieviel byte ? ich schaetz mal um die 50 Zeichen im schnitt.
annaehernd 100 Mill Zeilen oder ?
nun schreib mir mal ne performate funktion, die in einem Textfile mit ueber 100 Mill zeilen, an das erste Zeichen der 97.345.768ten Zeile springt !

Vielleicht bekommst nun nen gefuehl, wie nichttrivial dein problem ist !

Ciao ...