Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   gz-Datei: Decompress liefert nicht alle Zeilen (https://www.delphipraxis.net/209839-gz-datei-decompress-liefert-nicht-alle-zeilen.html)

philipp.hofmann 28. Jan 2022 21:00

gz-Datei: Decompress liefert nicht alle Zeilen
 
Hi,

bisher habe ich gz-Dateien immer mit dem folgenden Code ausgelesen:

Delphi-Quellcode:
function TPriceItemCompress.gzUnzip(filename:String):TStringList;
var
   LInput:TFileStream;
   LUnZip:TZDecompressionStream;
begin
   Result:=TStringList.Create(true);
   LInput:=TFileStream.Create(filename,fmOpenRead + fmShareDenyNone);
   LUnZip:=TZDecompressionStream.Create(LInput,15+32);
   Result.LoadFromStream(LUnzip);
   LUnZip.Free;
   LInput.Free;
end;
Jetzt habe ich eine gz-Datei vom Kunden, die nicht vollständig ausgelesen wird, sondern es werden nur die ersten 75 Zeilen ausgelesen. Hatte jemand schon mal dieses Problem?

Grüße, Philipp

KodeZwerg 28. Jan 2022 21:39

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
zLib liefert doch ein Binäres Archiv. Also ein array of Byte sozusagen. Beim entpacken muss doch auch erstmal alles in ein array of byte um es dann in was anderes zu Konvertieren.
Bestimmt habe ich da gerade einen Denkfehler.

himitsu 28. Jan 2022 23:33

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Da ist doch nicht etwa eine #0 in den "Text" reingerutscht? (die Lesefunktion des TStrings arbeitet leider blöderweise mit PChar)

philipp.hofmann 29. Jan 2022 07:36

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Hier der Umweg über einen String: Der String und auch schon LUnZip.Size sind zu kurz:

Delphi-Quellcode:
var
   LInput:TFileStream;
   LUnZip:TZDecompressionStream;
   strOutput: TStringStream;
   Splitted: TArray<String>;
   i:integer;
begin
   Result:=TStringList.Create(true);
   LInput:=TFileStream.Create(filename,fmOpenRead + fmShareDenyNone);
   LUnZip:=TZDecompressionStream.Create(LInput,15+32);
   strOutput:= TStringStream.Create;
   strOutput.CopyFrom(LUnZip, LUnZip.Size);
   i:=length(strOutput.DataString);
   Splitted := strOutput.DataString.Split([#10]);
   strOutput.free();
   for i:=0 to length(splitted)-1 do
     result.add(splitted[i]);
   LUnZip.Free;
   LInput.Free;
end;

KodeZwerg 29. Jan 2022 07:52

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Delphi-Quellcode:
var
   LInput:TFileStream;
   LUnZip:TZDecompressionStream;
   strOutput: TStringStream;
   Splitted: TArray<String>;
   i, x:integer;
begin
   Result:=TStringList.Create(true);
   LInput:=TFileStream.Create(filename,fmOpenRead + fmShareDenyNone);
   LUnZip:=TZDecompressionStream.Create(LInput,15+32); // '15+32' macht den Unterschied zwischen data-error und 'juhu'
   strOutput:= TStringStream.Create;
   strOutput.CopyFrom(LUnZip, LUnZip.Size);
   for x := Low(strOutput.DataString) to High(strOutput.DataString) do // das mit dem LUnZip machen... ich weiß nur gerade nicht wie
     if strOutput.DataString[x] = #0 then
       strOutput.DataString[x] = VK_RETURN;
   i:=length(strOutput.DataString);
   Splitted := strOutput.DataString.Split([#10]);
   strOutput.free();
   for i:=0 to length(splitted)-1 do
     result.add(splitted[i]);
   LUnZip.Free;
   LInput.Free;
end;
Könnte das vielleicht helfen? Nur hier getippt um zu veranschaulichen was ich meine...

philipp.hofmann 29. Jan 2022 09:12

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Wie gesagt, LUnZip.Size ist schon zu kurz. Da helfen keine Anpassungen danach. Mir ist nur unklar, warum er nicht das komplette File liest. Wenn ich die Datei mit 7zip entpacke, ist sie vollständig.

KodeZwerg 29. Jan 2022 09:25

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Was passiert denn wenn du das entpackte einfach mal als binär stream auf festplatte speicherst und anschaust?
Also ohne weitere konvertierung direkt schreiben.
Wenn es immernoch falsch ist, kann es ja nur am verwendeten komprimierungsverfahren liegen, was dein zlib nicht ganz beherrscht.

philipp.hofmann 29. Jan 2022 12:28

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Der unkomprimierte Teil ist ja richtig, er ist nur nach 75 von rund 500 Zeilen abgeschnitten und ich sehe, dass die Size von LInput (also der reinen Datei) noch richtig ist und die Size von LUnzip ist dann zu kurz.

KodeZwerg 29. Jan 2022 12:59

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Ich kann Dir nicht weiterhelfen aber Du hast ja Dir selbst schon eine passende Antwort gegeben "mit 7-zip funktioniert alles".... dann nutze das doch für dich. :-D
(Gibt es auch für Delphi/Pascal)

freimatz 29. Jan 2022 14:12

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Zitat:

Zitat von himitsu (Beitrag 1501387)
Da ist doch nicht etwa eine #0 in den "Text" reingerutscht? (die Lesefunktion des TStrings arbeitet leider blöderweise mit PChar)

Denke ich auch.

philipp.hofmann 29. Jan 2022 14:34

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Mit den JCL-Sourcen funktioniert es tatsächlich auch via Delphi-App.
Nachteil ist, dass man damit eine dll mitschleppen muss. Aber alle mal besser als vorab außerhalb der App manuell entpacken zu müssen.

KodeZwerg 29. Jan 2022 14:56

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Zitat:

Zitat von philipp.hofmann (Beitrag 1501403)
Mit den JCL-Sourcen funktioniert es tatsächlich auch via Delphi-App.
Nachteil ist, dass man damit eine dll mitschleppen muss. Aber alle mal besser als vorab außerhalb der App manuell entpacken zu müssen.

Falls Du 7-Zip meinst, in meinen Projekten binde ich die DLL in die Resource mit ein, in Roaming auf dem Zielsystem kurz geschrieben, genutzt, gelöscht.

himitsu 29. Jan 2022 15:45

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Da gibt es die Quellcodes und due Lizenz würde es meistens auch erlauben ... müsste nur mal wer für Delphi die OBJ generieren, dann kannst es direkt in die EXE linken.

Wie mit PNG, JPeg, RegEx, ... und ZLib :zwinker:

KodeZwerg 29. Jan 2022 16:48

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Das gibt es doch alles schon fertig @himitsu
Nur weiß ich nicht genau was er mit JCL meinte, vielleicht haben die 7zip supported, keine Ahnung, ich nutze keine Jedi Library.

dummzeuch 29. Jan 2022 16:54

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Zitat:

Zitat von KodeZwerg (Beitrag 1501409)
Nur weiß ich nicht genau was er mit JCL meinte

Die JCL unterstützt packen und entpacken in diversen Archiv-Formaten via 7zip.dll.

Redeemer 29. Jan 2022 16:55

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Wenn du fertig bist mit Lesen des DecompressionStreams, bis wie weit hat dann der Eingabestream gelesen? Kannst du an der Stelle noch einmal lesen?

Ich konnte allerdings keine Informationen finden, dass Gzip oder Zlib überhaupt mehrteilige Archive unterstützen, und wenn ich solche Archive mit dem Hexeditor erstelle, auch 7-Zip nicht dazu kriegen, dass es das akzeptiert.

KodeZwerg 29. Jan 2022 18:37

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Ich musste suchen, aber wenn ich mich nicht täusche habe ich zuletzt von hier mir 7zip support integriert, statisch.

Andreas13 29. Jan 2022 20:45

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Zitat:

Zitat von KodeZwerg (Beitrag 1501405)
Zitat:

Zitat von philipp.hofmann (Beitrag 1501403)
Mit den JCL-Sourcen funktioniert es tatsächlich auch via Delphi-App.
Nachteil ist, dass man damit eine dll mitschleppen muss. Aber alle mal besser als vorab außerhalb der App manuell entpacken zu müssen.

Falls Du 7-Zip meinst, in meinen Projekten binde ich die DLL in die Resource mit ein, in Roaming auf dem Zielsystem kurz geschrieben, genutzt, gelöscht.

Mit BTMemoryModule.pas https://github.com/DSPlayer/memorymodule/releases kannst Du eine DLL’s als Resource in Dein Programm (oder auch in Deine DLL) linken und die DLL-Routinen direkt aus dem Speicher aufrufen, ohne die DLL auf die Festplatte zu speichern. Damit kann man huckepack auch mehrere DLL’s mitnehmen, sofern das Urheberrecht nicht dagegenspricht.

Die kurze Beschreibung dazu lautet:
---------------------------------------------
„With BTMemoryModule (PASCAL code by www.dsplayer.com) a dynamic link library (DLL) can be loaded from memory without storing it on the hard-disk first.
BTMemoryModule is a Pascal port of Joachim Bauch's C / C++ Memory Module. The port includes the complete memorymodule pascal sourcecode and examples to demonstrate the use.
Compilers: Delphi and Lazarus Free Pascal / Operating Systems: Win95 up to Win8“
---------------------------------------------
Meine persönliche Erfahrung zeigt, daß BTMemoryModule auch unter Windows 10 einwandfrei funktioniert.

Gruß, Andreas

philipp.hofmann 29. Jan 2022 21:01

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
JCL=Jedi, damit war der Tipp genau richtig.

philipp.hofmann 31. Jan 2022 12:42

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Bei einer DLL stört mich weniger, wie ich sie beim Kunden deploye, sondern vielmehr, dass ich die Software nicht CrossPlatform nutzen kann. In meinem Umfeld ist es teilweise sehr hilfreich, wenn ich die Programme auch auf Linux-Servern direkt ausführen kann. Die Einbindung auf Windows via 7zip funktioniert. Soweit ich es verstehe, wäre die Einbindung via http://www.birtles.org.uk/programming/ auch nur per DLLs, also lebe ich jetzt zunächst einmal damit.
Ich habe in der Vergangenheit schon deutlich größere gz-Dateien entpacken können, keine Ahnung, warum ich hier den Umweg gehen muss.

himitsu 31. Jan 2022 12:54

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
wieso?

Dieses "DLL" gibt es auch als SO usw.
mußt dann nur beim Import den passenden Namen via {IFDEF LINUX} usw. angeben.

philipp.hofmann 31. Jan 2022 13:49

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Es reicht ja nicht aus, dass es für 7z Linux-so-Files gibt.
Ich habe es ja jetzt via JCL(=Jedi) implementiert. Die Standard-JCL-Implementierung ist Windows-only, wenn ich mich recht entsinne.
Es gibt eine experimentelle Linux Version in GitHub, aber da ist dann schon ein wenig mehr zu tun, als nur die so-Dateien einzubinden.
Ich werde jetzt nicht mehr Zeit investieren, da es jetzt ja zumindest unter Windows läuft.

user69 31. Jan 2022 15:08

AW: gz-Datei: Decompress liefert nicht alle Zeilen
 
Probier doch mal die zlibex.

https://www.base2ti.com/

Die setz ich ein. Die ist auch massiv schneller als die Delphi Implementierung.
Die nutzt auch die zlib und es benötigt keine dll.

Mit kleinen Anpassungen kannst du auch die aktuellsten obj files von Delphi genutzt werden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:19 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