Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TidTCP records senden/empfangen (https://www.delphipraxis.net/137459-tidtcp-records-senden-empfangen.html)

XXcD 5. Aug 2009 13:20

Re: TidTCP records senden/empfangen
 
Ich habe mich jetzt gerade nochmal mit dem Problem beschäftigt und wollte noch gerne ein Bild zusätzlich in den Stream laden.
Nur leider bekomme ich das nicht so richtig hin.

Delphi-Quellcode:
  type
  TProfile = class(TObject)
  id: String;
  name: string;
  image: TMemorystream;
  procedure LoadFromStream(AStream: TStream);
  procedure SaveToStream(AStream: TStream);
  end;

...

procedure TProfile.SaveToStream(AStream: TStream);
var
  iLen: Integer;
begin
  {String ID}
  iLen := Length(ID);
  AStream.Write(iLen, SizeOf(iLen));
  AStream.Write(ID[1], iLen);
  {String Name}
  iLen := Length(Name);
  AStream.Write(iLen, SizeOf(iLen));
  AStream.Write(Name[1], iLen);

  {TBitmap Picture}
  AStream.Write(image, SizeOf(image));
end;

procedure TProfile.LoadFromStream(AStream: TStream);
var
  iLen: Integer;
begin
  {String ID}
  AStream.Read(iLen, SizeOf(iLen));
  SetLength(ID, iLen);
  AStream.Read(ID[1], iLen);
  {String Name}
  AStream.Read(iLen, SizeOf(iLen));
  SetLength(Name, iLen);
  AStream.Read(Name[1], iLen);

    {TBitmap Picture}
  AStream.Read(image, SizeOf(image));
end;
Benutzt habe ich zum speichern einen Tmemorystream:
Delphi-Quellcode:
Profile:= TProfile.Create;
Profile.id:='1';
Profile.name:='huhu';
Profile.image:= TMemoryStream.Create;
Profile.image.loadfromfile(ExtractFilePath(ParamStr(0))+'Images/bg_Eingangshalle.png');
Stream:= TMemoryStream.Create;
Profile.SaveToStream(Stream);
Und das auslesen habe ich so gestaltet:
Delphi-Quellcode:
Profile1:= TProfile.Create;
Profile1.LoadFromStream(stream);
WriteLn(Profile1.id);
WriteLn(Profile1.name);
Profile1.image:= TMemoryStream.Create;
Profile1.image.SaveToFile('C:\Test.png');
Das ganze ist erstmal zum testen, beim speichern kommt kein fehler.
Allerdings beim auslesen werden unendlich neue Zeilen in der Konsole erzeugt.
Wo liegt denn da der Fehler?

Blup 6. Aug 2009 07:24

Re: TidTCP records senden/empfangen
 
Da Image ein Objekt ist und Objektvariablen nur Referenzen sind (also Zeiger auf einen Speicherbereich wo die eigentlichen Objektdaten liegen) ist SizeOf(image) immer 4. Mit der abgespeicherten Adresse des Objektes kann man aber nichts anfangen.
Das Objekt selbst soll auch nicht geladen werden, sondern nur die enthaltenen Daten.

Wie bei allen Daten mit variabler Länge wird erst die Größe und dann die eigentlichen Daten gespeichert/gelesen.
Delphi-Quellcode:
iLen := Image.Size;
AStream.Write(iLen, SizeOf(iLen));
Image.Position := 0;
AStream.CopyFrom(Image, iLen)


AStream.Read(iLen, SizeOf(iLen));
Image.Clear;
Image.CopyFrom(AStream, iLen);

XXcD 6. Aug 2009 10:43

Re: TidTCP records senden/empfangen
 
Ok leider bekomme ich beim auslesen immer den Fehler Zugriffsverletzung.

Delphi-Quellcode:
  type
  TProfile = class(TObject)
  id: String;
  name: Ansistring;
  image: TMemorystream;
  procedure LoadFromStream(AStream: TStream);
  procedure SaveToStream(AStream: TStream);
  end;

...

procedure TProfile.SaveToStream(AStream: TStream);
var
  iLen: Integer;
begin
  {String ID}
  iLen := Length(ID);
  AStream.Write(iLen, SizeOf(iLen));
  AStream.Write(PChar(ID)^, iLen);
  {String Name}
  iLen := Length(Name);
  AStream.Write(iLen, SizeOf(iLen));
  AStream.Write(PChar(Name)^, iLen);


  {memorystream image}
  iLen := Image.Size;
  AStream.Write(iLen, SizeOf(iLen));
  Image.Position := 0;
  AStream.CopyFrom(Image, iLen)
end;

procedure TProfile.LoadFromStream(AStream: TStream);
var
  iLen: Integer;
begin
  {String ID}
  AStream.Read(iLen, SizeOf(iLen));
  SetLength(ID, iLen);
  AStream.Read(PChar(ID)^, iLen);
  {String Name}
  AStream.Read(iLen, SizeOf(iLen));
  SetLength(Name, iLen);
  AStream.Read(PChar(Name)^, iLen);

  {memorystream image}
  AStream.Read(iLen, SizeOf(iLen));
  Image.Clear;
  Image.CopyFrom(AStream, iLen);
end;
Zum schreiben das sieht so aus:
Delphi-Quellcode:
        Profile:= TProfile.Create;
        Profile.id:='2';
        Profile.name:='huhu';
        Profile.image:= TMemorystream.Create;
        Profile.image.LoadFromFile(ExtractFilePath(ParamStr(0))+'Images/test.png');

        Stream:= TMemoryStream.Create;
        Profile.SaveToStream(Stream);
Und an anderer Stelle lese ich das so wieder aus:
Delphi-Quellcode:
        Profile1:= TProfile.Create;
        Stream.Position:=0;
        Profile1.LoadFromStream(stream);
        WriteLn(Profile1.id);
        WriteLn(Profile1.name);
        Profile1.image:= TMemorystream.Create;
        Profile1.image.SaveToFile('C:\test.png');
Oder kann ich vielleicht direkt den Typ image in den Stream laden, aber da weiß ich nicht welchen typ ich nehmen kann.

XXcD 6. Aug 2009 10:48

Re: TidTCP records senden/empfangen
 
Ahh habs gerade ebend rausgefunden musste nur MemoryStream.Create vor dem LoadFromStream ausführen.
Danke das hat mir echt weitergeholfen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:10 Uhr.
Seite 2 von 2     12   

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