AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Ordentliche Komprimierungsunit

Ein Thema von GreenHorn3600 · begonnen am 14. Aug 2009 · letzter Beitrag vom 18. Aug 2009
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#11

Re: Ordentliche Komprimierungsunit

  Alt 16. Aug 2009, 12:43
Zitat von alzaimar:
Code:
    zc := TCompressionStream.Create(clMax, ms1);
    try
      zc.CopyFrom(ms, 0);
    finally
      [color=#FF0000][b]zc.free;[/b][/color]
    end;
    lRateOfCompression.Caption := Format('%.3f', [[color=#FF0000][b]zc.CompressionRate[/b][/color]]);
Das kann gutgehen ... muss aber nicht
  Mit Zitat antworten Zitat
GreenHorn3600

Registriert seit: 24. Jun 2007
165 Beiträge
 
#12

Re: Ordentliche Komprimierungsunit

  Alt 16. Aug 2009, 13:22
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
zc.CopyFrom(ms, 0) Dies ist definiert als:
Delphi-Quellcode:
function TStream.CopyFrom(Source: TStream; Count: Int64): Int64;
...
begin
  if Count = 0 then
  begin
    Source.Position := 0;
    Count := Source.Size;
  end;
Weshalb Funktioniert dann zc.CopyFrom(ms, ms.size) nicht?

Dank Euch,
das GreenHorn
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#13

Re: Ordentliche Komprimierungsunit

  Alt 16. Aug 2009, 13:38
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:
Weshalb Funktioniert dann...nicht?
"Nicht funktionieren" ist eine sehr schlechte Fehlerbeschreibung. Kommt eine Fehlermeldung? Passiert einfach etwas anderes als erwartet? Wenn ja: was erwartest du und was passiert tatsächlich?
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
GreenHorn3600

Registriert seit: 24. Jun 2007
165 Beiträge
 
#14

Re: Ordentliche Komprimierungsunit

  Alt 16. Aug 2009, 14:14
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:
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;
@SirThornberry: beim aStream.copyfrom(ms, ms.size), sass wohl das Problem vor dem Bildschirm. Danke.

Greeny
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.768 Beiträge
 
Delphi 10.4 Sydney
 
#15

Re: Ordentliche Komprimierungsunit

  Alt 16. Aug 2009, 14:29
Vielleicht geht es so schneller?

Delphi-Quellcode:
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;
Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#16

Re: Ordentliche Komprimierungsunit

  Alt 16. Aug 2009, 14:53
Als Alternative zur ZLIB würde ich gerne noch Bei Google suchenTurboPower Abbrevia in den Raum werfen. Kommt sogar ohne DLL aus und kann neben ZIP auch CAB Archive verarbeiten
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#17

Re: Ordentliche Komprimierungsunit

  Alt 16. Aug 2009, 15:02
Zitat von Klaus01:
Vielleicht geht es so schneller?

Delphi-Quellcode:
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;
Grüße
Klaus
2 Fehler fallen sogar mir sofort auf:

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?"
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.768 Beiträge
 
Delphi 10.4 Sydney
 
#18

Re: Ordentliche Komprimierungsunit

  Alt 16. Aug 2009, 15:20
Zitat von jfheins:
2. astream müsste als var Parameter deklariert werden. So wird der übergebene Stream freiegegeben, und der lokale nicht.
Meine Absicht war, dass der übergebene Stream freigegeben wird und anschließend die
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
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#19

Re: Ordentliche Komprimierungsunit

  Alt 16. Aug 2009, 16:02
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

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 ). 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
  Mit Zitat antworten Zitat
GreenHorn3600

Registriert seit: 24. Jun 2007
165 Beiträge
 
#20

Re: Ordentliche Komprimierungsunit

  Alt 18. Aug 2009, 00:15
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
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz