![]() |
String mit gzip (ent)zippen
Hallo miteinander.
Ich stehe vor folgendem "Problem": ich möchte gerne einen einfachen String per gzip zippen bzw. entzippen. Es sollen keine Archive oder so auf Festplatte geschrieben werden, lediglich der gzip-Algorithmus auf einen String im hauptspeicher angewendet werden. ich habe im Forum schon von der Unit ZLib gelesen und dass die gzip beherrsche. U.a. habe ich folgendes Beispiel gefunden und bereits versucht, auf mein Problem umzubauen:
Delphi-Quellcode:
Ich habe versucht, statt TFileStream die Klassen TMemoryStream und TStringStream zu verwenden, aber ohne den gewünschten Erfolg. Ich habe es einfach nicht hinbekommen. Außerdem habe ich mich schonmal mit den Abrevia-Komponenten beschäftigt, aber dort auch keine gefunden, die mir lediglich einen Datenstrom im Hauptspeicher zippt, ohne diesen anschließend auf Festplatte schreiben zu wollen. Möglich wäre das zur Not, klar, aber einfach unschön.
uses ZLib, SysUtils;
Packen: procedure Compress(InputFileName, OutputFileName: string); var InputStream, OutputStream: TFileStream; CompressionStream: ZLib.TCompressionStream; begin InputStream:=TFileStream.Create(InputFileName, fmOpenRead); try OutputStream:=TFileStream.Create(OutputFileName, fmCreate); try CompressionStream:=TCompressionStream.Create(clMax, OutputStream); try CompressionStream.CopyFrom(InputStream, InputStream.Size); finally CompressionStream.Free; end; finally OutputStream.Free; end; finally InputStream.Free; end; end; Entpacken: procedure Decompress(InputFileName, OutputFileName: string); var InputStream, OutputStream: TFileStream; DeCompressionStream: ZLib.TDeCompressionStream; begin InputStream:=TFileStream.Create(InputFileName, fmOpenRead); try OutputStream:=TFileStream.Create(OutputFileName, fmCreate); try DecompressionStream:=TDecompressionStream.Create(OutputStream); try DecompressionStream.CopyFrom(InputStream, InputStream.Size); finally DecompressionStream.Free; end; finally OutputStream.Free; end; finally InputStream.Free; end; end; Daher meine Fragen:
Vielen lieben Dank schonmal!!! |
Re: String mit gzip (ent)zippen
ZLib macht gZip ? Nein.
Zitat:
![]() PS.: Vill ist es ja auch nicht GZip was deinen Hauptspeicherstring betrifft... :mrgreen: |
Re: String mit gzip (ent)zippen
Zitat:
![]() |
Re: String mit gzip (ent)zippen
Also die normale ZLib-Unit macht kein gZip, in der ZLib.Pas (Version 1.1.3) sind auch keine
Funktionen dazu implementiert. |
Re: String mit gzip (ent)zippen
Habe nun mal die Funktionen aus deinem Link ausprobiert. Ließen sich anfangs nicht kompilieren, weil die darin verwendeten Funktionen CompressBuf und DeCompressBuf als ersten Parameter einen Zeiger erwarten. Habe das "[1]" entfernt und ein "@" vor das Input geschrieben. Dann gings. Ich habe zu Testzwecken dann zwei Memofelder auf ein Formular geklatscht und den Inhalt des einen auf Knopfdruck komprimiert und im andern angezeigt. Hat funktioniert. Daraufhin wollte ich das ganze wieder dekomprimieren und bekam dann die Fehlermeldung "Ungültige Zeigeroperation" in der Funktion DeCompressBuf. Woran kann das liegen? Bin nicht sonderlich zeigerbewandt, nur zur Info :wink: !
Zum Thema ZLib/gzip: sorry, hatte dein zitat von oben nicht aufmerksam genug gelesen :mrgreen: . |
Re: String mit gzip (ent)zippen
Zitat:
|
Re: String mit gzip (ent)zippen
Auch das hatte ich schon, aber kommt das Zeigertechnisch nicht aufs selbe raus, ob ich die Adresse des ersten Characters nehme oder die Adresse des kompletten String?
Den Pointerfehler resultiert übrigens wohl daraus, dass ich als Input/Output der Funktionen die Text-Eigenschaft der memos verwendet habe. Da beim Comprimieren Steuerzeichen entstehen, die das memo nicht darstellen kann, tauscht es die Zeichen gegen diese schwarzen Kästchen aus, die wiederum beim Einlesen einen Murks erzeugen. So oder ähnlich :mrgreen: . |
Re: String mit gzip (ent)zippen
Zitat:
Du hast doch als Parameter einen "normalen" String verwendet? @xyz liefert einen Zeiger auf die stringrefferenz @xyz[1] zeigt auf das erste Zeichen, also den Stringinhalt xyz[1] gibt das Zeichen zurück [edit] hab ausversehn editiert, statt mich zitiert ... bekomm jetzt den Originalbeitrag nich mehr komplett zusammen :freak: |
Re: String mit gzip (ent)zippen
Zitat:
EDIT: Auf alle Fälle geht nun alles wie gewünscht. Der Grund für die ungültige Zeigeroperation hat sich bestätigt. Wenn ich den komprimierten String ganz normal als String zwischenspeicher und nicht direkt in die Text-Eigenschaft des Memos klatsche, dann funktionierts. |
Re: String mit gzip (ent)zippen
Nein, XYZ ist nur ein Zeiger auf einen "Record", wo dann die Stringdaten (Referenzzähler, Längenangabe und der Stringinhalt) drin sind.
sozusagen so:
Delphi-Quellcode:
Du kannst es dir wie eine KlassenReferenz vorstellen.
TAnsiString = Record
RefCount: Integer; Len: Integer; Data: Array[1..Len+1] of AnsiChar; // +1, da noch ein #0 hinten dran ist End; Pointer(xyz) = @TAnsiString.Data @xyz zeigt also nur auf einen Pointer, wo drin steht an welcher Stelle sich der StringRecord befindet. "nur" PChar(xyz) und @xyz[1] zeigen also auf den Stringinhalt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:28 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 by Thomas Breitkreuz