![]() |
Komprimiertes Speichern von Virtual Stringtree / Stream
Morgen zusammen,
folgendes Problem: Habe eine VST mit SEHR VIELEN Zeilen, die ich via VST.savetostream in einen Filestream speichere. Bei sehr großen Datenmengen wird die gespeicherte Datei allerdings schnell mal 1GB groß = unverhältnismäßig groß für reine Textdaten. Daher habe ich eine bei den Schweizern gefundene Streamkomprimierung eingebaut. Letztere übergibt den komprimierten Stream allerdings an TMemorystream; folglich habe ich VST.savetostream zunächst an TMemorystream übergeben, um es dann zu komprimieren und dann zu speichern (via Umleitung in TFilestream). Leider scheint das speichern der VST-Daten in TMemorystream unendlich viel langsamer zu sein bzw. kommt nie zum Ende; hat jemand eine Ahnung warum bzw. wie ich das umgehen könnte (außer zuerst unkomprimiert in TFilestream zu speichern, dann wieder zu laden, zu komprimieren und wieder zu speichern..)? Das ist der relevante Code:
Delphi-Quellcode:
Danke und Euch allen ein schönes WE,
uses ZLib;
procedure CompressStream(inpStream, outStream: TStream); var InpBuf, OutBuf: Pointer; InpBytes, OutBytes: Integer; begin InpBuf := nil; OutBuf := nil; try GetMem(InpBuf, inpStream.Size); inpStream.Position := 0; InpBytes := inpStream.Read(InpBuf^, inpStream.Size); CompressBuf(InpBuf, InpBytes, OutBuf, OutBytes); outStream.Write(OutBuf^, OutBytes); finally if InpBuf <> nil then FreeMem(InpBuf); if OutBuf <> nil then FreeMem(OutBuf); end; end; procedure TForm1.Button8Click(Sender: TObject); var kompstream: tstream; stream: TMemorystream; begin stream:= TMemoryStream.Create; kompstream:= TFileStream.Create(savedlg2.filename, fmCreate); try vst.SaveToStream(stream); CompressStream(stream, kompstream); finally stream.free; kompstream.Free; end; end; Frieder |
AW: Komprimiertes Speichern von Virtual Stringtree / Stream
|
AW: Komprimiertes Speichern von Virtual Stringtree / Stream
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. |
AW: Komprimiertes Speichern von Virtual Stringtree / Stream
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 |
AW: Komprimiertes Speichern von Virtual Stringtree / Stream
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. |
AW: Komprimiertes Speichern von Virtual Stringtree / Stream
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 ![]() ![]() 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:
|
AW: Komprimiertes Speichern von Virtual Stringtree / Stream
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 |
AW: Komprimiertes Speichern von Virtual Stringtree / Stream
Zitat:
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. |
AW: Komprimiertes Speichern von Virtual Stringtree / Stream
Sonntag, 09.00 Uhr - und schon so viele aktiv! Respekt :)
Zitat:
Zitat:
- 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? |
AW: Komprimiertes Speichern von Virtual Stringtree / Stream
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). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:23 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