Solved

read from TMemoryStream fails

Posted on 1998-09-21
11
204 Views
Last Modified: 2010-04-06
I want to use a stream for example for clipboard operations. If I read and write the stream within the same procedure (Button3Click) it occures successfull. If I split this procedure into the Button1Click+Button2Click procedures I loose in the line marked as {B} the value of RecordDestination.Wort. This value has been modified in a mysterious way at this point.
Up to now I have no expirience using streams. May be I'm wrong but I think it should be possible to to use streams in this way.


type
      TMyRecord = record
            Zahl: cardinal;
            Wort: String;
      end;

var
      Form1: TForm1;
      MyStream: TMemoryStream;

implementation

procedure TForm1.Button1Click(Sender: TObject);
var
      RecordSource: TMyRecord;
begin
  RecordSource.Zahl:=123;
  RecordSource.Wort:='BullShit';
    MyStream:=TMemoryStream.Create;
    MyStream.Clear;
    MyStream.Write(RecordSource,SizeOf(RecordSource));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
      RecordDestination: TMyRecord;
begin
      MyStream.Seek(0,soFromBeginning);
      MyStream.Read(RecordDestination,MyStream.Size);
      MyStream.Free;
{A}   Edit5.Text:=IntToStr(RecordDestination.Zahl);
      Edit6.Text:=RecordDestination.Wort;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
      RecordSource, RecordDestination: TMyRecord;
begin
  RecordSource.Zahl:=124;
  RecordSource.Wort:='Bulleye';
    MyStream:=TMemoryStream.Create;
    MyStream.Clear;
    MyStream.Write(RecordSource,SizeOf(RecordSource));
      MyStream.Seek(0,soFromBeginning);
      MyStream.Read(RecordDestination,MyStream.Size);
      MyStream.Free;
{B}   Edit5.Text:=IntToStr(RecordDestination.Zahl);
      Edit6.Text:=RecordDestination.Wort;
end;
0
Comment
Question by:Saxon
  • 5
  • 4
  • 2
11 Comments
 
LVL 5

Expert Comment

by:inter
ID: 1340387
My dear friend,
you can not simply read and write the records containing pointers or dynamic  strings:
instead you may change the record in to
TMyRecord = record
    Zahl: cardinal;
    Wort: ShortString;
end;
and try again,
regards, igor
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1340388
Saxon,

igor is right.
the type "string" is kind of (not exactly) a pointer to an array of char. That means your record is only 8 bytes long. If you use igor's variant then your record will be 4+256 bytes long, since the characters of your string are then really stored in your record.
If 256 bytes are not enough for you respectively if you want dynamic string because of some other reasons you can save your use the following code:

procedure TForm1.Button1Click(Sender: TObject);
var RecordSource : TMyRecord;
    i1           : integer;
begin
  RecordSource.Zahl:=123; RecordSource.Wort:='BullShit';
  MyStream:=TMemoryStream.Create; // you don't need to clear it...
  try
    // writing:
    MyStream.Write(RecordSource.Zahl,sizeOf(cardinal));
    i1:=length(RecordSource.Wort);
    MyStream.Write(i1,sizeOf(integer));
    MyStream.Write(PChar(RecordSource.Wort)^,i1);
    // reading:
    MyStream.position:=0;
    MyStream.Read(RecordSource.Zahl,sizeOf(cardinal));
    MyStream.Read(i1,sizeOf(integer));
    SetLength(RecordSource.Wort,i1);
    MyStream.Read(PChar(RecordSource.Wort)^,i1);
  finally MyStream.Free end;
end;

Regards, Madshi.

P.S: Schöne Grüße...
0
 

Author Comment

by:Saxon
ID: 1340389
Great, it works, but please explain me at last, why it works in the other case (and sometime - I tried different other versions - in the splitted manner too).
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1340390
Because you saved the pointer to the string and reloaded it. So if the record (and the string) still exists the loaded pointer is still correct.
Which way do you want to use? Igor's or mine?
0
 

Author Comment

by:Saxon
ID: 1340391
Thx, for your string->widestring->string hint too!
For the moment I'll use Igor's way, but the points I'd like to give to you. Your answer was more helpful for my understanding. Hope Igor agrees, thanks to you too!
Lutz
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 5

Expert Comment

by:inter
ID: 1340392
Sure man,
please answer Madshi,
igor
0
 
LVL 20

Accepted Solution

by:
Madshi earned 100 total points
ID: 1340393
Thanx Saxon, thanx igor...   :-)

P.S: igor, why do you call yourself "igor" instead of "Igor"?
0
 
LVL 5

Expert Comment

by:inter
ID: 1340394
nothing specific friend, is just a SHIFT saving...
regards, igor (or may be I am a poet like Cummings)
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1340395
Igor,

ok, you can call me "madshi" to save another shift...   :-)

Regards, Madshi.
0
 
LVL 5

Expert Comment

by:inter
ID: 1340396
nothing specific friend, is just a SHIFT saving...
regards, igor (or may be I am a poet like Cummings)
0
 
LVL 5

Expert Comment

by:inter
ID: 1340397
ok madshi ;-) sorry for reposting...
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now