AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Abspeichern von Objekten ??

Ein Thema von matz · begonnen am 17. Okt 2005 · letzter Beitrag vom 19. Okt 2005
Antwort Antwort
Seite 1 von 2  1 2      
matz

Registriert seit: 9. Sep 2003
31 Beiträge
 
#1

Abspeichern von Objekten ??

  Alt 17. Okt 2005, 20:16
Ich beschäftige mich gerade mit dem abspeichern von Daten

die Daten sind in einer StringList als Opjekte gespeichert
Delphi-Quellcode:
  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;
der Versuch die Daten zu speichern und anschließend wieder zu laden sah recht vielversprechend aus
Delphi-Quellcode:

// 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;
leider geht das beim Start des Programmes aber nicht mehr

Delphi-Quellcode:
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;
nun meine Frage kann das überhaupt funktionieren ?

schon mal betsen Dank für die Hilfe
gruß Matz
  Mit Zitat antworten Zitat
Benutzerbild von Rastaman
Rastaman

Registriert seit: 6. Jan 2005
Ort: Lübbecke
575 Beiträge
 
Turbo C++
 
#2

Re: Abspeichern von Objekten ??

  Alt 17. Okt 2005, 20:20
Warum nimmst du nicht Records
Chuck Norris has counted to infinity ... twice!
  Mit Zitat antworten Zitat
Benutzerbild von Kroko1999
Kroko1999

Registriert seit: 21. Apr 2005
Ort: Spremberg
455 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Abspeichern von Objekten ??

  Alt 17. Okt 2005, 20:29
Der Typ string ist nur ein Pointer,
daher
Delphi-Quellcode:
Stream.Write (Length(MyString),SizeOf(Integer));
Stream.Write (MyString[1],Length(MyString));
Da sprach der Stumme zum Blinden: "Du wirst sehen ..."
oder
Wer lesen kann, ist klar im Vorteil!
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#4

Re: Abspeichern von Objekten ??

  Alt 17. Okt 2005, 20:36
Rastaman war fast richtig, richtig:
Warum nimmst du nicht Records Collections ?
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#5

Re: Abspeichern von Objekten ??

  Alt 17. Okt 2005, 22:31
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...
  Mit Zitat antworten Zitat
Benutzerbild von Taladan
Taladan

Registriert seit: 5. Aug 2003
Ort: Osnabrück
505 Beiträge
 
Delphi 2005 Professional
 
#6

Re: Abspeichern von Objekten ??

  Alt 17. Okt 2005, 23:02
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.

http://www.delphipraxis.net/internal...ct.php?t=56836
Marco
Wer Rechtschreibfehler findet, der darf sie behalten

Carpe Diem - Nutze den Tag (und zwar den ganzen!)
  Mit Zitat antworten Zitat
matz

Registriert seit: 9. Sep 2003
31 Beiträge
 
#7

Re: Abspeichern von Objekten ??

  Alt 18. Okt 2005, 12:05
Hallo Taladan

ich habe mir die Beiträge
Beitrag 1
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
  Mit Zitat antworten Zitat
Benutzerbild von Taladan
Taladan

Registriert seit: 5. Aug 2003
Ort: Osnabrück
505 Beiträge
 
Delphi 2005 Professional
 
#8

Re: Abspeichern von Objekten ??

  Alt 19. Okt 2005, 00:10
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:
      else if typ = 'tStringListthen 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;
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)
Marco
Wer Rechtschreibfehler findet, der darf sie behalten

Carpe Diem - Nutze den Tag (und zwar den ganzen!)
  Mit Zitat antworten Zitat
matz

Registriert seit: 9. Sep 2003
31 Beiträge
 
#9

Re: Abspeichern von Objekten ??

  Alt 19. Okt 2005, 09:52
nachdem ich mir diverse Beiträge gestern durchgelesen habe, habe ich folgendes probiert

Laden:
Delphi-Quellcode:
      
       else if typ = 'TStringListthen 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;
Speichern:

Delphi-Quellcode:
      else if typ = 'TStringListthen 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;
wobei ich heute Deinen Vorschlag die Stringliste direkt beim speichern als Memorystream zu speichern mal testen werde

Delphi-Quellcode:
s := Tstringlist.Create;
s := (GetObjectProp(self, PropList^[i].Name) as tStringList);
zur Zeit erzeuge ich relativ unelegant und nicht in das Konzept passend direkt in der Routine 'TMyObjectlist.savetostream'
Delphi-Quellcode:
  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;
den daraus resultierenden Memorystream speichere ich dann in den Hauptstream

des geht zur Zeit sehr gut
  Mit Zitat antworten Zitat
Benutzerbild von Grishnak
Grishnak

Registriert seit: 15. Sep 2005
Ort: Neu-Ulm
111 Beiträge
 
RAD-Studio 2009 Arc
 
#10

Re: Abspeichern von Objekten ??

  Alt 19. Okt 2005, 11:15
Ich würde der OHeader-Klasse zwei Methoden zum Speichern bzw. Laden verpassen:

Delphi-Quellcode:
  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;
Meine Speicher- bzw. Laden-Prozedur kann dann so aussehen (ich würde mir aber eine eigene SL_Header-Klasse implementieren!):

Delphi-Quellcode:
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;
Das Ganze ist nicht getestet, aber ich hoffe - sollte es nicht gleich funktionieren - das Prinzip ist verständlich!
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
  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 09:02 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