![]() |
JEDI JCL Compression OnProgress wie verwenden
Ich frage mich schon seit einer Ewigkeit wie man von den JEDI JCL-Komponenten einen richtig funktionierenden OnProgress-Event implementiert.
Mein Ziel ist ein Event bei welchem ich grob gesagt gucken kann, welche Datei gerade komprimiert wird und wenn der Vorgang fertig ist möchte ich das in einem Log festhalten. Das Event hat folgende Kopfzeile
Delphi-Quellcode:
(Sender: TObject; const Value, MaxValue: Int64); Wie verwendet man den Event richtig? Was muss ich mit Value und MaxValue machen, damit ich korrekt abfragen kann, wann eine Datei fertig komprimiert wurde? Ich bin leider eine regelrechte Niete was Mathematik angeht und sehe hier nur chinesische Zeichen und einen Berg von Problemen vor mir. |
AW: JEDI JCL Compression OnProgress wie verwenden
Darf man hier Beiträge wieder nach oben holen? Wenn nicht, bitte löschen :oops:
|
AW: JEDI JCL Compression OnProgress wie verwenden
Hab' die Teil noch nie benutzt.
Was steht denn in Value? MaxValue dürfte ja quasi das Ende sein. Also mal 'ne Progressbar nehmen. Minimum auf 0, Maximum auf MaxValue und Position auf Value. Tippe mal darauf, dass man damit (ohne Mathematik) 'nen Fortschrittsbalken bekommt, an dem man sehen kann, wieviel erledigt wurde und wieviel noch fehlt. Je nach Typ der Progressbar, zeigt sie von alleine die Prozentangabe des Fortschrittes an. Ansonsten Kettensatz oder Dreisatz: ?% = Value MaxValue = 100% Entspricht: ? = Value * 100 / MaxValue Auf 'nem Label also:
Delphi-Quellcode:
Label.Caption := Format('%d von %d (%3.2f%%) erledigt.',[Value, MaxValue, Value * 100.00 / MaxValue]
|
AW: JEDI JCL Compression OnProgress wie verwenden
Es geht mir nicht um die ProgressBar sondern viel mehr darum herauszufinden, wann eine Datei fertig verarbeitet wurde.
Value enthält soweit ich verstanden habe die Größe in Bytes der Daten, die schon verarbeitet wurden. MaxValue die Gesamtgröße. Die Dateigröße jeder einzelnen Datei liegt mir vor und ich kann sie abfragen. Jetzt muss ich nur wissen wie ich mit Value und MaxValue + eventuellen ZwischenVariablen wie "OldValue" errechne, wann eine Datei fertig komprimiert wurde. Beispiel 165 - 15 = 150 Value - Dateigröße = OldValue Klingt einfach, funktioniert aber nicht. |
AW: JEDI JCL Compression OnProgress wie verwenden
Der Vergleich Value = MaxValue sollte schon reichen. Ob die Datei dann aber auch schon wieder geschlossen ist, ist daraus nicht klar. Es kann also sein, dass die Komprimierung fertig ist, die Zieldatei aber noch gesperrt ist.
|
AW: JEDI JCL Compression OnProgress wie verwenden
MaxValue enthält aber die Größe in Bytes aller zu komprimierenden Dateien.
|
AW: JEDI JCL Compression OnProgress wie verwenden
Wenn in Value steht, wieviel Byte komprimiert wurden und MaxValue wieviel insgesamt zu komprimieren sind, sich aber beide Werte auf die Gesamtmenge und nicht die einzelne Datei beziehen, dann geht das einfach nicht.
Wenn Du weißt, in welcher Reihenfolge die Dateien komprimiert werden und Du die Größe der einzelnen Dateien weißt, dann kannst Du jeweils ausrechnen, welche Datei gerade "In Mache ist". Sinngemäß sowas in der Art:
Delphi-Quellcode:
Ob das performant und sinnvoll ist, sei erstmal dahingestellt.
Summe := 0;
for i := 0 to Dateiliste.Count - 1 do begin Summe := Summe + Dateiliste[i].Dateigroesse; if Summe > Value then begin Label1.Caption := Format('zuletzt komprimierte Datei: %s (%d Byte)',[Dateiliste[i - 1].Dateiname,Dateiliste[i - 1].Dateigroesse]); Label2.Caption := Format('aktuell wird die Datei %s (%d Byte) komprimiert ...',[Dateiliste[i].Dateiname,Dateiliste[i].Dateigroesse]); break; end; end; |
AW: JEDI JCL Compression OnProgress wie verwenden
Zitat:
Ich verstehe langsam nichts mehr. Ein Testverzeichnis enthält 1800 Dateien. Alle 1800 werden komprimiert aber nur rund 600-700 (manchmal so manchmal so) werden vom obigen Code sowie von meinem erfasst. In meiner Test-logdatei sind zu gefühlt 99% nur Dateien bis 50KB. Eine einzige Datei von 20MB wurde erfasst, der Rest > 50KB etwa nicht. So wie es aussieht ist das JCLCompression OnProgress-Event einfach schlecht umgesetzt. |
AW: JEDI JCL Compression OnProgress wie verwenden
Protokolliere doch in dem Ereignis einfach mal nur Value und schaue, wie sich der Wert verändert.
Eventuell wird er ja nicht dateiabhängig aufgerufen, sondern mengenabhängig oder alle x% der Gesamtmenge oder alle y Byte. Dann muss das Ereignis nicht bei jeder Datei aufgerufen werden. [EDIT] Wenn man in die Sourcen schaut, kann man erkennen / erahnen, dass der Aufruf dieses Ereignisses von der zur Komprimierung genutzten packervariante abhängig ist. Die Häufigkeit des Aufrufes könnte also bei ZIP-Dateien vollkommen anders sein, als bei 7z ... |
AW: JEDI JCL Compression OnProgress wie verwenden
Zitat:
Value geht so lange hoch bis es MaxValue erreicht und dann ist der Vorgang beendet. |
AW: JEDI JCL Compression OnProgress wie verwenden
Das ist klar, aber ist Value immer 100 kb (oder sowas) größer oder irgendwie einfach nur "unstrukturiert" anders, aber auf jeden Fall höher?
Wenn das Ereignis nicht bei jeder Datei aufgerufen wird, kannst Du damit nicht protokollieren, wann eine Datei fertig gepackt wurde. Ausgehend von den Quelltexten, dürfte das, was Du vorhast, mit dem Werkzeug nicht gehen, zumindest kann ich kein passendes Ereignis, Attribut ... finden. |
AW: JEDI JCL Compression OnProgress wie verwenden
Doch das Event wird bei jeder Datei aufgerufen.
Das ganze Event scheint irgendwie kaputt zu sein denn
Delphi-Quellcode:
gibt auch immer 0 zurück.
ShowMessage((Sender as TJclCompressionArchive).CurrentItemIndex.ToString);
Grundlage für das Event ist übrigens TNotifyEvent. Ich würde die .Compress;-Routine ja selber gerne einbauen statt die fertige von JCLCompression.pas zu nutzen aber ich kann sie einfach in der Datei nicht finden. Ich habe gerade eine erstaunliche Entdeckung gemacht. Mein alter Code funktioniert komischerweise und sämtliche Dateien werden erfasst. Aber nur wenn ich die ZIP-Methoden verwende statt 7z. Meine aktuelle Berechnung im Event ist
Delphi-Quellcode:
Funktioniert bei TJclZipCompressArchive wunderbar, bei TJcl7zCompressArchive nicht.
if ((Sender as TJclCompressionArchive).ItemCount > _globals.CurrentFileIndex) then
begin _globals.FileSizeTmp := (Sender as TJclCompressionArchive).Items[_globals.CurrentFileIndex].FileSize; Inc(_globals.BytesCopied, Value - _globals.ValueOld); if ((_globals.BytesCopied - _globals.BytesCopiedTmp) >= _globals.FileSizeTmp) then Inc(_globals.CurrentFileIndex); _globals.ValueOld := Value; end; |
AW: JEDI JCL Compression OnProgress wie verwenden
Wie ich bereits weiter oben vermutet hatte:
Der Aufruf der Routine ist nicht dateiabhängig, sondern von der Variante des genutzten Packers. Wenn ZIP die Routine pro Datei aufruft, heißt das noch lange nicht, dass ein anderer Packer sich aus so verhalten muss. |
AW: JEDI JCL Compression OnProgress wie verwenden
Ob das pro Datei einmal oder mehrmals aufgerufen wird weiß ich nicht.
Aber egal wie oft, die Berechnung müsste doch eigentlich jedes Szenario erfassen? |
AW: JEDI JCL Compression OnProgress wie verwenden
Deine Ursprungsfrage lautet:
Zitat:
Du könnstest allenfalls mit der oben skizzierten Routine einen Näherungswert ermitteln. Wenn alle Dateien in einer Liste bekannt sind und vom Packer in der dort enthaltenen Reihenfolge gepackt werden, kannst Du per Summierung der bekannten Dateigröße und dem Vergleich mit Value ermitteln, welche Dateien bis zu diesem Zeitpunkt bereits gepackt wurden. Wurden zwischen zwei Aufrufen des Ereignisses mehrere Dateine gepackt, so kannst Du nur feststellen, dass diese Dateien im Zeitraum zwischen den Ereignisaufrufen gepackt wurden. Aber einen genauen Zeitpunkt kannst Du nicht ermitteln. Sofern die Packer in der gepackten Datei ein Verzeichnis vorhalten, dass das Komprimierdatum enthält, kannst Du diese Information nach dem Fertigstellen ermitteln. Aber ansonsten sind es nur Näherungswerte, bei denen die Genauigkeit schlimmstenfalls gegen 0 tendiert oder inetwa die Genauigkeit des :glaskugel: -lesens aufweisen. |
AW: JEDI JCL Compression OnProgress wie verwenden
Zitat:
Das heißt ich muss den Index (XYZ) selber erhöhen um auf DateiListe[XYZ] zuzugreifen. Und hier funktioniert Summe := Summe + Dateigroesse nicht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz