![]() |
Abspeichern von Objekten ??
Ich beschäftige mich gerade mit dem abspeichern von Daten
die Daten sind in einer StringList als Opjekte gespeichert
Delphi-Quellcode:
der Versuch die Daten zu speichern und anschließend wieder zu laden sah recht vielversprechend aus
OHeader = class(TObject)
public HDR_TYP : String[20]; No : String; Datum : tDateTime; Path : String; Edi : String; PDF : String; Status : String; Nachricht_Typ : String; Nachricht_Name : String; Bezugsnr : String; Benutzer_ID : String; RegistrierNr : TStringList; RegistrierNr1 : String; EdifactNr : String; INH_NR : String; end;
Delphi-Quellcode:
leider geht das beim Start des Programmes aber nicht mehr// Daten speichern if not FileExists(Filename) then TmpStream := TFileStream.Create('C:\test.dat', fmCreate) else TmpStream := TFileStream.Create(Filename, fmOpenReadWrite); Len := SL_Header.Count; TmpStream.Write(len, SizeOf(len)); // abspeichern wie viele Datensätze for I := 0 to SL_Header.Count - 1 do begin Header := SL_Header.Objects[i] as oHeader; TmpStream.Write(Header, SizeOf(oHeader)); end; TmpStream.Free; // gespeicherte Daten gleich wieder einlesen TmpStream := TFileStream.Create('c:\test.dat', fmOpenRead); tmpStream.Read(len, SizeOf(len)); sl_Header.Clear; for I := 0 to len - 1 do Begin Header := oHeader.Create; header.Path := ''; tmpStream.Read(Header, SizeOf(oHeader)); sl_header.AddObject(Header.No,Header); end; tmpstream.free;
Delphi-Quellcode:
nun meine Frage kann das überhaupt funktionieren ?
TmpStream := TFileStream.Create('c:\test.dat', fmOpenRead);
tmpStream.Read(len, SizeOf(len)); for I := 0 to Len-1 do Begin Header := oHeader.Create; tmpStream.Read(Header, SizeOf(oHeader)); SL_Header.AddObject(Header.No,Header); end; tmpstream.free; schon mal betsen Dank für die Hilfe gruß Matz |
Re: Abspeichern von Objekten ??
Warum nimmst du nicht Records :gruebel:
|
Re: Abspeichern von Objekten ??
Der Typ string ist nur ein Pointer,
daher
Delphi-Quellcode:
Stream.Write (Length(MyString),SizeOf(Integer));
Stream.Write (MyString[1],Length(MyString)); |
Re: Abspeichern von Objekten ??
Rastaman war fast richtig, richtig: Warum nimmst du nicht Records Collections ? :gruebel: |
Re: Abspeichern von Objekten ??
Du kannst auch Objekte selber nicht so einfach in den Stream schreiben wie du es machst, weil du damit nur die Adresse des Objektes im Speicher in die Datei ablegst - und diese ist natürlich nicht mehr die gleiche wenn du das Objekt mal wieder lädst. Und vor allem fehlen noch die Daten der Objekte selber...
|
Re: Abspeichern von Objekten ??
Um dir das ganze hin und her mit der Speicherprozedur zu ersparen, ließ dir mal meinen Beitrag zu polimorphen Objekten und deren Speicherung durch. Sollte dir die Arbeit doch ziemlich ersparen.
![]() |
Re: Abspeichern von Objekten ??
Hallo Taladan
ich habe mir die Beiträge ![]() und den von Dir oben genannten mal angesehen und getestet. In der Version 1 verwendest Du sogar TStrings leider werden beim Speichern keine Stringwerte gespeichert ** EDIT wenn der Typ in der Routine TBaseObject.SaveToStream(Writer:TWriter) richtig ist wird auch geschrieben ** Somit bleibt nur noch die Stringliste könntest Du mir noch mal ein wenig behilflich sein Danke schon mal viele Grüße Matz |
Re: Abspeichern von Objekten ??
Nachdem ich mir damals Abend um Abend um die Ohren gehauen hab, um Streams zu speichern über TWriter und TReader was scheinbar nicht möglich ist (zumindest mir nicht möglich war), würde ich deinen TStringList String für String abspeichern lassen.
Das ganze würde ich so angehen (erweiterung zur bekannten Speicherroutine):
Delphi-Quellcode:
Ich hoffe das bringt dich auf den richtigen Weg, da ich kein Win32 mehr installiert habe, kann ich es nicht ausprobieren. Wenns klappt würde ich mich auf eine Antwort (mit evtl. richtigen ergebnis freuen)
else if typ = 'tStringList' then begin
s := Tstringlist.Create; s := (GetObjectProp(self, PropList^[i].Name) as tStringList); Writer.WriteInteger(s.Count); for length := 0 to s.Count do Writer.WriteString(s[length]); s.Free; end; |
Re: Abspeichern von Objekten ??
nachdem ich mir diverse Beiträge gestern durchgelesen habe, habe ich folgendes probiert
Laden:
Delphi-Quellcode:
Speichern:else if typ = 'TStringList' then Begin dStrings := TStringList.Create; MemoryStream := TMemoryStream.Create; MemoryStream.Position := 0; size := Reader.ReadInteger; memorystream.SetSize(size); reader.Read(MemoryStream.Memory^, Size); MemoryStream.Position := 0; dstrings.LoadFromStream(MemoryStream); SetObjectProp(self, PropList^[i].Name, dstrings); end;
Delphi-Quellcode:
wobei ich heute Deinen Vorschlag die Stringliste direkt beim speichern als Memorystream zu speichern mal testen werde
else if typ = 'TStringList' then Begin
MemoryStream := TMemoryStream.Create; MemoryStream.Position := 0; sl_temp.SaveToStream(MemoryStream); MemoryStream.Position := 0; size := MemoryStream.Size; writer.WriteInteger(size); MemoryStream.Position := 0; Writer.Write(MemoryStream.Memory^, size); end;
Delphi-Quellcode:
zur Zeit erzeuge ich relativ unelegant und nicht in das Konzept passend direkt in der Routine 'TMyObjectlist.savetostream'
s := Tstringlist.Create;
s := (GetObjectProp(self, PropList^[i].Name) as tStringList);
Delphi-Quellcode:
den daraus resultierenden Memorystream speichere ich dann in den Hauptstream
for i:=0 to c-1 do begin
// Schreiben des TBaseObjects-Typen-Namen WriteClassRef(Writer, Items[i]); // Speichern der gewünschten Informationen Header := Items[i] as lHeader; sl_temp := tStringlist.create; sl_Temp := header.RegistrierNr; Items[i].SaveToStream(Writer); sl_temp.Free; end; des geht zur Zeit sehr gut |
Re: Abspeichern von Objekten ??
Ich würde der OHeader-Klasse zwei Methoden zum Speichern bzw. Laden verpassen:
Delphi-Quellcode:
Meine Speicher- bzw. Laden-Prozedur kann dann so aussehen (ich würde mir aber eine eigene SL_Header-Klasse implementieren!):
OHeader = class(TObject)
public { ... } procedure WriteToStream(AStream: TStream); procedure ReadFromStream(AStream: TStream); { ... } end; { ... } procedure OHeader.WriteToStream(AStream: TStream); var s: string; len: word; begin // HDR_TYP AStream.WriteBuffer(HDR_TYP[0], SizeOf(HDR_TYP)); // No len := Length(No); AStream.WriteBuffer(len, SizeOf(len)); AStream.WriteBuffer(No[1], len); // Datum AStream.WriteBuffer(Datum, SizeOf(Datum)); // Path len := Length(Path); AStream.WriteBuffer(len, SizeOf(len)); AStream.WriteBuffer(Path[1], len); { ... } // RegistrierNr s := RegistrierNr.Text; len := Length(s); AStream.WriteBuffer(len, SizeOf(len)); AStream.WriteBuffer(s[1], len); { ... } end; procedure OHeader.ReadFromStream(AStream: TStream); var s: string; len: word; begin // HDR_TYP AStream.ReadBuffer(HDR_TYP[0], SizeOf(HDR_TYP)); // No AStream.ReadBuffer(len, SizeOf(len)); SetLength(No, len); AStream.ReadBuffer(No[1], len); // Datum AStream.ReadBuffer(Datum, SizeOf(Datum)); // Path AStream.ReadBuffer(len, SizeOf(len)); SetLength(Path, len); AStream.ReadBuffer(Path[1], len); { ... } // RegistrierNr AStream.ReadBuffer(len, SizeOf(len)); SetLength(s, len); AStream.ReadBuffer(s[1], len); RegistrierNr.Text := s; { ... } end;
Delphi-Quellcode:
Das Ganze ist nicht getestet, aber ich hoffe - sollte es nicht gleich funktionieren - das Prinzip ist verständlich!
procedure DatenSpeichern(Filename: string);
var TmpStream: TFileStream; Header: OHeader; len, i: integer; begin if not FileExists(Filename) then TmpStream := TFileStream.Create('C:\test.dat', fmCreate) else TmpStream := TFileStream.Create(Filename, fmOpenWrite); len := SL_Header.Count; TmpStream.Write(len, SizeOf(len)); // abspeichern wie viele Datensätze for i := 0 to SL_Header.Count - 1 do begin Header := SL_Header.Objects[i] as OHeader; Header.WriteToStream(TmpStream); end; FreeAndNil(TmpStream); end; procedure DatenLaden(Filename: string); var TmpStream: TFileStream; Header: OHeader; len, i: integer; begin if not FileExists(Filename) then begin ShowMessage('Datei "'+Filename+'" nicht gefunden!'); Exit; end; TmpStream:=TFileStream.Create(Filename, fmOpenRead); TmpStream.ReadBuffer(len, SizeOf(len)); SL_Header.Clear; // ACHTUNG: bereits eingefügte Objekte werden mMn NICHT (per .Free) freigegeben! for i := 0 to len - 1 do begin Header := OHeader.Create; Header.ReadFromStream(TmpStream); SL_Header.AddObject(Header.No, Header); end; FreeAndNil(TmpStream); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:55 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 by Thomas Breitkreuz