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      
friedemann2009

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

Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 13. Aug 2011, 08:57
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:
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;
Danke und Euch allen ein schönes WE,
Frieder
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Komprimiertes Speichern von Virtual Stringtree / Stream

  Alt 13. Aug 2011, 10:55
Mit diesen Funktionen arbeite ich problemlos.
Vielleicht findest Du dort einen Anhaltspunkt.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#3

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
 
#4

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
 
#5

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
43.196 Beiträge
 
Delphi 12 Athens
 
#6

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)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

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
 
#7

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
43.196 Beiträge
 
Delphi 12 Athens
 
#8

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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (14. Aug 2011 um 07:58 Uhr)
  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: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
43.196 Beiträge
 
Delphi 12 Athens
 
#10

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).
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  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 11:21 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