Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Record aus stream auslesen (https://www.delphipraxis.net/20878-record-aus-stream-auslesen.html)

Spurius 24. Apr 2004 17:19


Record aus stream auslesen
 
Hallo,
wie kann ich in folgendem Code das Record 'Test2' mit den Daten aus dem Stream füllen?
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
 TTest=record
  a,b,c: String;
 end;
var
  Form1: TForm1;
  Test: TTest;
  TestStream: TMemoryStream;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 Test.a := 'a';
 Test.b := 'b';
 Test.c := 'c';
 TestStream := TMemoryStream.Create;
 TestStream.Write(Test,sizeof(Test));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 TestStream.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
Var Test2: TTest;
begin
  //Was muss ich hier schreiben, um das ecord Test2 mit Daten zu füllen?
end;

end.
Gruß
Spurius

Christian Seehase 24. Apr 2004 18:41

Re: Record aus stream auslesen
 
Moin Spurius,

erst einmal zu der Struktur:

Du solltest den Memorystream auch nur einmal erstellen, dazu wäre dann das OnCreate des Formulares geeignet.
Ersatzweise käme auch die Kombination initialization/finalization in Frage.

Bevor Du ausliest, müsstest Du die Eigenschaft Position des Streams auf den Wert setzen, den sie vor dem Schreiben der Daten hat, i.d.R. also wohl 0.
Anschliessend, kannst Du dann mit der Eigenschaft Read auslesen.

Was Du aber auf jeden Fall berücksichtigen musst:
Wenn Du einen Record speicherst, der Felder vom Typ String enthält, so speicherst Du nicht die Werte der Felder, sondern die Adressen der Werte, denn der Typ String ist nur ein Pointer.
Die Grösse Deines Record Typs ist immer 12, egal welche Strings Du den Feldern zuordnest.

Spurius 24. Apr 2004 20:07

Re: Record aus stream auslesen
 
Wie müsste ich dass dann machen, dass ich String-Werte(oder halt die Buchstaben) richtig auslesen kann? Code-Bsp. wär nicht schlecht.

deccer 24. Apr 2004 20:48

Re: Record aus stream auslesen
 
Delphi-Quellcode:
type
  TTest = record
    A: string;
    B: string;
    C: string;
    D: integer;
    E: byte;
    F: double;
  end;

procedure WriteRecordToStream(Stream: TStream; ARecord: TTest);
var
  lLength: integer;

begin
  with ARecord do begin
    lLength := Length(A);
    Stream.Write(lLength, 4); // 4 Bytes = SizeOf(Integer)
    Stream.Write(Pointer(A)^, lLength);
    lLength := Length(B);
    Stream.Write(lLength, 4);
    Stream.Write(Pointer(B)^, lLength);
    lLength := Length(C);
    Stream.Write(lLength, 4);
    Stream.Write(Pointer(C)^, lLength);
    Stream.Write(D, 4); // 4 Bytes = SizeOf(D) = SizeOf(Integer)
    Stream.Write(E, 1); // 1 Byte = SizeOf(E) = SizeOf(Byte)
    Stream.Write(F, 8); // 8 Bytes = SizeOf(F) = SizeOf(Double);
  end;
end;

procedure ReadRecordFromStream(Stream: TStream; ARecord: TTest);
var
  lLength: integer;

begin
  with ARecord do begin
    Stream.Read(lLength, 4);
    SetLength(A, lLength);
    Stream.Read(Pointer(A)^, lLength);
    Stream.Read(lLength, 4);
    SetLength(B, lLength);
    Stream.Read(Pointer(B)^, lLength);
    Stream.Read(lLength, 4);
    SetLength(C, lLength);
    Stream.Read(Pointer(C)^, lLength);
    Stream.Read(D, 4);
    Stream.Read(E, 1);
    Stream.Read(F, 8);
  end;
end;

procedure TForm1.ButtonRecordSpeichernClick(Sender: TObject);
var
  lMS: TMemoryStream;
  lRecord: TTest;

begin
  lRecord.A := 'hallo';
  lRecord.B := 'du';
  lRecord.C := 'da';
  lRecord.D := 1000;
  lRecord.E := 255;
  lRecord.F := Now; // Now is vom typ double
  lMS := TMemoryStream.Create;
  WriteRecordToStream(lMS, lRecord);
  lMS.SaveToFile('c:\myrecord.dat');
  FreeAndNil(lMS);
end;

procedure TForm1.ButtonRecordLadenClick(Sender: TObject);
var
  lMS: TMemoryStream;
  lRecord: TTest;

begin
  lMS := TMemoryStream.Create;
  lMS.LoadFromFile('c:\myrecord.dat');
  ReadRecordFromStream(lMS, lRecord);
  FreeAndNil(lMS);
  with lRecord do
    ListBox1.Items.Add(Format('%s %s %s %d %d %3.2f', [A, B, C, D, E, F]));
end;
[edit=MrSpock]Delphi Tags eingefügt. Mfg, MrSpock[/edit]

Muetze1 24. Apr 2004 20:52

Re: Record aus stream auslesen
 
Moin!

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TTest=record
    a,b,c: ShortString;
  end;
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    Procedure FormCreate(Sender: TObject);
    Procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen } 
    Test : TTest;
    TestStrm : TMemoryStream;
  public
    { Public-Deklarationen } 
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject);
begin
  Test.a := 'a';
  Test.b := 'b';
  Test.c := 'c';

  TestStrm.Position := 0;
  TestStrm.Write(Test, sizeof(TTest));
end;

procedure TForm1.Button2Click(Sender: TObject);
Var
  Test2: TTest;
begin
  TestStrm.Position := 0;
  TestStrm.Read(Test2, SizeOf(TTest));
end;

Procedure TForm1.FormCreate(Sender: TObject);
begin
  TestStrm := TMemoryStream.Create;
end;

Procedure TForm1.FormDestroy(Sender: TObject);
begin
  TestStrm.Free;
end;

end.
MfG
Muetze1

kiar 24. Apr 2004 20:52

Re: Record aus stream auslesen
 
hallo deccer,

willkommen in der dp.
dann setze bitte dein quelltext mit den delphi tags.

coller spruch :thuimb:

raik

Muetze1 24. Apr 2004 20:56

Re: Record aus stream auslesen
 
Moin!

@deccer: ich würde da nicht einen TypeCast auf einen Pointer machen bei einem Stream, sondern eher direkt die Adresse des ersten Zeichens angeben:

Delphi-Quellcode:
Stream.Write(A[1], lLength);
MfG
Muetze1

Spurius 24. Apr 2004 21:21

Re: Record aus stream auslesen
 
Hallo,
@Muetze1
So gehts! Aber wenn ich das Programm beende bekomme ich eine Zugriffsverletzung :!:

Muetze1 24. Apr 2004 23:13

Re: Record aus stream auslesen
 
Moin!

Zitat:

Zitat von Spurius
Hallo,
@Muetze1
So gehts! Aber wenn ich das Programm beende bekomme ich eine Zugriffsverletzung :!:

An dem oben geposteten Code kann ich nix erkennen was Probleme machen sollte, daher die Frage: was hast du sonst noch drinne in deinem Code bzw. was machst du sonst noch?

MfG
Muetze1

Spurius 25. Apr 2004 11:13

Re: Record aus stream auslesen
 
Hier ist nochmal der Code:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
 TTest=record
  a,b,c: String;
 end;
var
  Form1: TForm1;
  Test: TTest;
  TestStream: TMemoryStream;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 Test.a := 'a';
 Test.b := 'b';
 Test.c := 'c';
 TestStream := TMemoryStream.Create;
 TestStream.Write(Test,sizeof(Test));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 TestStream.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
Var Test2: TTest;
begin
  TestStream.Position := 0;
  TestStream.Read(Test2, SizeOf(TTest));
  label1.Caption := test2.b;
end;

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:28 Uhr.
Seite 1 von 2  1 2      

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-2025 by Thomas Breitkreuz