AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Komprimiertes Speichern von Virtual Stringtree / Stream
Thema durchsuchen
Ansicht
Themen-Optionen

Komprimiertes Speichern von Virtual Stringtree / Stream

Ein Thema von friedemann2009 · begonnen am 13. Aug 2011 · letzter Beitrag vom 14. Aug 2011
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.222 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 13. Aug 2011, 10:59
Ich würde hier eher ein generelles Redesign machen und die Datenhaltung einer Embedded/Desktop-DB übergeben. Und im VST werden nur die angezeigten Daten aus der DB geladen.
Damit dürfte bei richtiger Programmierung dein Lade/Speicherperformance-Problem der Vergangenheit angehören.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
friedemann2009

Registriert seit: 10. Feb 2010
49 Beiträge
 
#2

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 14. Aug 2011, 07:19
Moin zusammen,

danke für die Hinweise. Die (De-)Compress-Routinen hatte ich ja bereits, habe es dennoch nochmal damit getestet. Das Problem liegt wohl an anderer Stelle: Mein Prog hängt sich offenbar auf, wenn ich versuche, _sehr große_ Daten via VST.savetostream in ein TMemorystream zu speichern. Offenbar komme ich da an eine Grenze. Wenn ich den VST-Stream direkt an TFileStream übergebe, habe ich das Problem nicht (klar, große Daten brauchen länger, aber es geht doch wesentlich schneller bzw. kommt überhaupt zu einem Ende im Vergleich zu TMemoryStream). - Wie gesagt, wird dann die Datei aber viel zu groß.

- Sehe ich das richtig, wenn ich wohl doch zuerst in TFilestream speichern, dann wieder laden, komprimieren und dann erneut in TFilestream speichern muss (unter Umgehung von TMemoryStream) oder gibt es noch eine andere Möglichkeit, mit der dieses 'Zwischenspeichern' umgehen könnte?

Danke und schönen Samstag,
frieder
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 14. Aug 2011, 07:44
Die Grenze heißt 32-Bit und kann nur 2GB RAM pro Programm verwalten.

Somit wirst du gezwungen sein erst in einen temp. FileStream zu schreiben und dann zu komprimieren.
Oder du erstellst dir eine TFileStream-Ableitung die sofort komprimiert.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.346 Beiträge
 
Delphi 12 Athens
 
#4

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 14. Aug 2011, 07:45
Welche Delphiversion nutzt du eigentlich?

Ich weiß nicht seit wann es den gibt, aber vergiß nicht, daß die vielen Daten, beim TMemorystream erstmal in den Arbeitsspeicher rein müssen.
Bei 1 GB kann es schnell mal eng werden und dann kopiert der auch ständig/öfters seinen Speicher um, um ihn zu vergrößeren.
(eventuell kann es helfen, wenn man den speicher vor SavetoStream über .Size schonmal vorbelegt)

Es gibt da auch Delphi-Referenz durchsuchenTZCompressionStream und Delphi-Referenz durchsuchenTZDecompressionStream in der unit ZLib, diese Stream hängst du direkt an den TFileStream und übergibst sie der Speicherroutine, damit wird direkt komprimiert und gleich abgespeichert ... spart enorm viel an Arbeitsspeicher.


PS: Ein VirtualStringTree ist doch eigentlich dafür gedacht nur "externe" Daten anzuzeigen und nicht um als Datencontainer genutzt zu werden?
Demnach sollte er selber keine Daten besitzen, welche man abspeichern wöllte ... Speichern tut man ja eigentlich die Originaldaten.

PSS:
Zitat:
procedure CompressStream(inpStream, outStream: TStream);
Eigentlich sollten derartige Prozeduren schon fertig in der Unit ZLib rumliegen. (also mindestens seit TDE/D2006)
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (14. Aug 2011 um 07:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 14. Aug 2011, 07:51
Der Punkt ist doch das wir im Speicher Daten rumliegen haben die 1GB groß sind.
Diese kommen jetzt in einen TMemoryStream rein.
Nach meinem Verständnis benötigt das Prog jetzt 2GB RAM.

Und ab da streikt 32-Bit
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.346 Beiträge
 
Delphi 12 Athens
 
#6

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 14. Aug 2011, 07:54
Und ab da streikt 32-Bit
Ach, kein Problem ... wozu gibt es denn XE2?


2GB ... bei ein 1GB rumliegenden Daten, den sonstigen geladenen DLLs/EXE und dem restlichen belegten Speicher, welches alles wild verteilt im virtuellen Arbeitsspeicher rumliegt, wird es sowieso schwer überhaupt noch ein halbes GB zusammenhängend für den MemoryStream zu finden.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (14. Aug 2011 um 07:58 Uhr)
  Mit Zitat antworten Zitat
friedemann2009

Registriert seit: 10. Feb 2010
49 Beiträge
 
#7

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 14. Aug 2011, 08:08
Sonntag, 09.00 Uhr - und schon so viele aktiv! Respekt

Die Grenze heißt 32-Bit und kann nur 2GB RAM pro Programm verwalten.
Ok, das wusste ich nicht.. Das dürfte def. eines der Probleme sein..

Welche Delphiversion nutzt du eigentlich?
Nutze noch immer D5... Ich weiß, ein Aufrüsten wäre langsam mal nötig, aber die Professionals sind so teuer, dass ich mir das als wissenschaftlicher Laienprogrammierer (der aus einem anderen Fach kommt) gerade nicht unbedingt leisten kann..

- Und: Ja, ich weiß, dass die VST nur zur Visualisierung dient/dienen soll. Aber als ich die VST kennengelernt habe, war ich so begeistert, dass ich darüber nicht mehr nachgedacht habe. Jetzt müsste ich das komplette Design (~400 Seiten Code) ändern.. Das wäre dann was für eine Version 4,5 o.ä. derzeit bin ich an 2.x)

Habe den Stream jetzt mal temporär gespeichert und anschließend komprimiert. Das klappt auch. - Fehlt nur noch eine Progressbar, aber da muss ich mich erst mal in den Foren umsehen, wie ich den Speicher-/Laden-/(De)Komprimier-Fortschritt abgreifen kann.

Danke Euch schon mal!

Gruß, frieder

EDIT: Hm, finde ich gerade nichts zur Fortschrittsanzeige; hat da noch jemand einen Tipp?

Geändert von friedemann2009 (14. Aug 2011 um 08:14 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.346 Beiträge
 
Delphi 12 Athens
 
#8

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 14. Aug 2011, 08:17
Wegen dem Fortschritt: Man weiß ja nicht, wie groß die Datei mal wird, also ist eine prozenduale Fortschrittsanzeige unmöglich, also beim Erstellen der Datei.
(maximal näherungsweise möglich, indem man die endgültige Größe schätzt)

Du kannst dir aber den FileStream ableiten und in den Schreib-/Lesemethoden deine Fortschrittsanzeige aktualisieren.

Beim Schreiben schreibst du dann z.B. "x Byte verarbeitet" und beim Auslesen "x von y byte verarbeitet" (das nochmalige Speichern hast du dabei über den Lesezyklus mit abgedeckt, da beides ja gleichzeitig geschieht, es sei denn du willst life mit ausgeben, von wieviel auf wieviel aktuell runterkomprimiert wurde).

PS: Eine nette eMail an germany.info@embarcadero.com und man bekommt oftmals noch eine Lizenz für Turbo Delphi (kleineres Delphi 2006).
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
friedemann2009

Registriert seit: 10. Feb 2010
49 Beiträge
 
#9

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 14. Aug 2011, 08:20
Welche Delphiversion nutzt du eigentlich?
Es gibt da auch Delphi-Referenz durchsuchenTZCompressionStream und Delphi-Referenz durchsuchenTZDecompressionStream in der unit ZLib, diese Stream hängst du direkt an den TFileStream und übergibst sie der Speicherroutine, damit wird direkt komprimiert und gleich abgespeichert ... spart enorm viel an Arbeitsspeicher.
Hm, das hörte sich doch interessant an, zumal es vlt. doch die Performance erhöhen könnte. Nur, was meinst Du mit "an den TFileStream dranhängen"?

Gruß, frieder

EDIT: Ok, hat sich wohl erledigt; TCompressionStream gibt es lt. Forum erst ab D7...

Geändert von friedemann2009 (14. Aug 2011 um 08:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.346 Beiträge
 
Delphi 12 Athens
 
#10

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 14. Aug 2011, 09:43
Im Prinzip könnte man sowas selber Implementieren.

TZCompressionStream ist nach außen ein Stream, welchen man nun an SaveToStream übergeben könnte.
Im Constructor gibt man diesem aber einen anderen Stream mit, wie z.B. einen TFileStream.

Alles was reinkommt, wird komprimiert und an den anderen Stream weitergegeben.




Dieser komprimierte Stream ist aber mit nichts kompatibel, kann also nur mit dem beigelegten TDecompessStream entpackt werden.
Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}

uses SysUtils, SimpleCompressStream;

var
  C: TCompessStream;
  D: TDecompessStream;
  X: AnsiString;
begin
  try
    C := TCompessStream.Create(ChangeFileExt(ParamStr(0), '.dat'));
    try
      X := '123456789';
      C.WriteBuffer(X[1], Length(X));

      X := 'abcdefghij'; // Mehreres in einem Kompressionsteil simulieren
      C.WriteBuffer(X[1], Length(X));

      C.Flush; // einen neuen Kompressionsteil simulieren
      X := 'klmnopqrstubwxyz';
      C.WriteBuffer(X[1], Length(X));
    finally
      C.Free;
    end;

    D := TDecompessStream.Create(ChangeFileExt(ParamStr(0), '.dat'));
    try
      SetLength(X, 9);
      D.ReadBuffer(X[1], Length(X));
      WriteLn(X); // 123456789

      SetLength(X, 10);
      D.ReadBuffer(X[1], Length(X));
      WriteLn(X); // abcdefghij

      SetLength(X, 16);
      D.ReadBuffer(X[1], Length(X));
      WriteLn(X); // klmnopqrstubwxyz
    finally
      D.Free;
    end;

    D := TDecompessStream.Create(ChangeFileExt(ParamStr(0), '.dat'));
    try
      SetLength(X, 35);
      D.ReadBuffer(X[1], Length(X));
      WriteLn(X); // 123456789abcdefghijklmnopqrstubwxyz
    finally
      D.Free;
    end;
    WriteLn('ende...');
    ReadLn;
  except
    on E: Exception do begin
      WriteLn(E.ClassName, ': ', E.Message);
      ReadLn;
    end;
  end;
end.
Angehängte Dateien
Dateityp: pas SimpleCompressStream.pas (4,9 KB, 7x aufgerufen)
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (14. Aug 2011 um 09:46 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 23:47 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