![]() |
Re: Ordentliche Komprimierungsunit
Zitat:
|
Re: Ordentliche Komprimierungsunit
Hallo alzaimar,
dank Dir. Ich bin ja auch nur ein GreenHorn. Hab aber noch ein paar fragen dazu. Mein Stream (TStream) kennt kein .Clear wie kann man das dennoch wieder säubern? Andere Frage, beim Stream schreibst Du
Delphi-Quellcode:
Dies ist definiert als:
zc.CopyFrom(ms, 0)
Delphi-Quellcode:
Weshalb Funktioniert dann
function TStream.CopyFrom(Source: TStream; Count: Int64): Int64;
... begin if Count = 0 then begin Source.Position := 0; Count := Source.Size; end;
Delphi-Quellcode:
nicht?
zc.CopyFrom(ms, ms.size)
Dank Euch, das GreenHorn |
Re: Ordentliche Komprimierungsunit
Wenn clear nicht vorhanden ist kann man auch einfach mit dem Property-Size die Größe auf 0 setzen.
Oder was in den meisten Fällen performanter ist - die Größe gleich auf den richtigen Wert setzen. In diesem Fall also:
Delphi-Quellcode:
procedure CompressStream(ms: TStream);
var zc: TCompressionStream; ms1: TMemoryStream; begin ms1 := TMemoryStream.Create; try zc := TCompressionStream.Create(clMax, ms1); try zc.CopyFrom(ms, 0); finally zc.free; end; lRateOfCompression.Caption := Format('%.3f', [zc.CompressionRate]); ms.size := ms1.size; ms.position := 0; ms1.postion := 0; ms.CopyFrom(ms1, ms1.size); finally ms1.free; end; end; Zitat:
|
Re: Ordentliche Komprimierungsunit
Hallo Wissende,
kann man diesen Code noch optimieren? Geht darum, dass der Stream aStream komprimiert wird und der komprimierte anschliessend wieder im aStream zurückgegeben wird.
Delphi-Quellcode:
@SirThornberry: beim aStream.copyfrom(ms, ms.size), sass wohl das Problem vor dem Bildschirm. Danke.
procedure CompressStream(aStream: TStream);
var zc: TZCompressionStream; ms: TMemoryStream; begin ms := TMemoryStream.Create; try zc := TZCompressionStream.Create(ms, zcMax); try zc.CopyFrom(aStream, 0); finally zc.Free; end; aStream.Size := 0; aStream.copyFrom(ms, 0); finally ms.Free; end; Greeny |
Re: Ordentliche Komprimierungsunit
Vielleicht geht es so schneller?
Delphi-Quellcode:
Grüße
procedure CompressStream(aStream: TStream);
var zc: TZCompressionStream; ms: TStream; begin ms := (ms as TMemoryStream).Create; zc := TZCompressionStream.Create(ms, zcMax); try zc.CopyFrom(aStream, 0); finally zc.Free; end; aStream.Free aStream:=ms; end; Klaus |
Re: Ordentliche Komprimierungsunit
Als Alternative zur ZLIB würde ich gerne noch
![]() |
Re: Ordentliche Komprimierungsunit
Zitat:
1. ms := (ms as TMemoryStream).Create; sollte ne Exception werfen, wenn dann so: ms := TMemoryStream.Create; 2. astream müsste als var Parameter deklariert werden. So wird der übergebene Stream freiegegeben, und der lokale nicht. Zur Logik: Ich darf nen beliebigen Stream reinpacken, und der wird hinterrücks freigeben und durch einen Memorystream ersetzt. Als hätte der Autor überlegt "Hmmm ... wie könnte ich das programmieren, damit der Zweck zwar erfüllt wird, aber die Funktion trotzdem möglichst unerwartet reagiert?" |
Re: Ordentliche Komprimierungsunit
Zitat:
Adresse des intern erzeugten Streams zugewiesen bekommt. So könnte das unkopieren entfallen. Im Punkt 1 gebe ich Dir recht. Objekte die als Paramter einer Routine übergeben werden müßen nicht als var gekennzeichnet werden damit Änderungen auch ausserhalb der Routine wahrgenommen werden. Grüße Klaus |
Re: Ordentliche Komprimierungsunit
Wenn man ein Objekt an eine Funktion "normal" übergibt, geschieht dies mit call-by-value. Es wird also der Zeiger, der auf das Objekt zeigt kopiert und der Funktion gegeben.
Alles was im Objekt ist, wird natürlich nicht kopiert und Änderungen wirken sich auf den Aufrufer aus. Der Zeiger selbst wird aber immernoch kopiert - d.h. es gibt 2 Zeiger (einen beim Aufrufer und einen in der Funktion). Wenn du also auf deiesen Zeiger ein aValue.Free() ausführst wird das Orginal-Objekt zerstört. Jetzt sagst du: aValue := ms; damit wird der lokalen Kopie des Zeigers die Adresse des internen Streams zugewiesen. Der äußere Zeiger bleibt unverändert. Beim Verlassen der Funktion wird der Zeiger dann auch weggeworfen. Wer auch immer diese Funktion aufruft, hat danach einen ungültigen Zeiger und ein Speicherleck :stupid: Der var-Parameter würde dafür sogen, dass der Zeiger nicht kopiert wird, sondern sozusagen ein Zeiger auf den Zeiger übergeben wird. Dann kannst du auch den Orginal-Zeiger ändern. Gut ist das alles abder trotzdem nicht (weshalb sich diese Frage beim normalen Programmieren auch nicht stellt :P ). Stell dir vor, du öffnest eine Datei und willst die komprimieren. Du übergibt also nen Filestream und bekommt ... einen Memorystream zurück, in dem die komprimierte Datei steht. Der Filestream wurde freigegeben. Tolle Logik :mrgreen: |
Re: Ordentliche Komprimierungsunit
Halo Mirage,
danke für den Tipp, aber das ganze sollte schon mit Bordmitteln funktionieren, oder zumindest für OS und kommerzielle Programme (kostenlos) einsetzbar sein. Und da gibt es dann halt nicht mehr viel :-( Gut, die ZLib, komprimiert jetzt mal, aber so ordentlich auch nicht. Sie schafft da Grad mal 1,44%, aber immerhin... BTW: @alzaimer: der TZCompress ist der Name aus der unit zLib unter D2.9 unter D2.6 ist das ganze noch ohne Z . Dafür kann er keine Memorystreams. Kennst Du hier vielleicht einen Trick, um ihm Memorystreams beizubringen (in D2.6)? Grüße Greeny |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:40 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