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
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.174 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.279 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
friedemann2009

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

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


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 07:52 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