Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

WriteComponent & ReadComponent with dynamic object arrays...

Posted on 2004-08-16
3
Medium Priority
?
642 Views
Last Modified: 2011-09-20
hello all,
Im hoping someone can help me.
Im saving some objects in my app to a file when it exits, and then reading them back when my app restarts.
Some of the objects are static and some objects are dynamic though.

The code Im listing first works perfectly. It was a test project I made to see if this will work
------------------------------------------------------------------------
var
  F: TFileStream;
  CurDir : String;
  lblTMP : array[0..2] of THTMLabel;

procedure TForm1.btnWriteClick(Sender: TObject);
{ WRITE THE OBJECT TO A FILE VIA STREAM }
var
  i: integer;
begin
  CurDir := ExtractFileDir(Application.ExeName);
  F := TFileStream.Create(CurDir + '\label.dat', fmCreate or fmShareCompat);
  try
    { create a few objects }
    for i := 0 to 2 do
      lblTMP[i] := THTMLabel.Create(nil);
    { add the text to one of the objects }
    with lblTMP[1] do begin
        HTMLText.add("some test to show');
        visible := false;
    end;
    { write the objects (save) }
    for i := 0 to 2 do
      F.WriteComponent(lblTMP[i]);

  finally
    for i := 0 to 2 do
      lblTMP[i].Free;
    F.Free;
  end;
end;

procedure TForm1.btnReadClick(Sender: TObject);
{ READ THE OBJECT FROM A FILE VIA STREAM }
var
  i: integer;
begin
  CurDir := ExtractFileDir(Application.ExeName);
  if FileExists(CurDir + '\label.dat') then begin
    F := TFileStream.Create(CurDir + '\label.dat', fmOpenRead or fmShareDenyWrite);
    try
      for i := 0 to 2 do
        lblTMP[i] := THTMLabel.Create(nil);
      for i := 0 to 2 do
        F.ReadComponent(lblTMP[i]);
      edit2.Text := lblTMP[1].Text;
    finally
      for i := 0 to 2 do
        lblTMP[i].Free;
      F.Free;
    end;
  end;

end;

-------------------------------------------------------------------------
The above code works, but the following does not even though its basically the same
-------------------------------------------------------------------------
type
  TOpenWeekRec = record   { OPEN THIS WEEK }
    trCount    : longint;
    Title      : string[255];
    Link       : string[255];
    RawTitle   : string;
    RawPlayers : string;
    RawPlot    : string;
    RawBuzz    : string;
  end;

  public
    { Public declarations }
    arrOpenWeek : Array of TOpenWeekRec;

var
  arrTMP2 : array of array[0..6] of THTMLabel;
  F: TFileStream;
  CurDir: String;

procedure WriteObjects();
var
  i, x: integer;
begin
  CurDir := ExtractFileDir(Application.ExeName);
  F := TFileStream.Create(CurDir + '\results.dat', fmCreate or fmShareCompat);
  try
    F.WriteComponent(HTMLTreeview1);
    F.WriteComponent(HTMLTreeview2);
    F.WriteComponent(HTMLabel1);
    F.WriteComponent(HTMLabel2);
    { SAVE THE ARRAY COUNT FOR WHEN WE READ IT BACK IN }
    F.Write((arrOpenWeek[0].trCount), sizeof(arrOpenWeek[0].trCount));
    { SAVE DYNAMIC ARRAY NOW }
    SetLength(arrTMP2,arrOpenWeek[0].trCount);
    try
      { CREATE TEMP OBJECTS TO PUT STRINGS INTO }
      x:= 0;
      for i := 0 to high(arrOpenWeek) do
        for x := 0 to 6 do
          arrTmp2[i,x] := THTMLabel.Create(nil);
      { INSERT TEXT INTO THE OBJECTS }
      x:=0;
      for i := 0 to high(arrOpenWeek) do begin
        for x := 0 to 6 do begin
          case x of
            0: arrTmp2[i,x].HTMLText.add(IntToStr(arrOpenWeek[i].trCount));
            1: arrTmp2[i,x].HTMLText.add(arrOpenWeek[i].Title);
            2: arrTmp2[i,x].HTMLText.add(arrOpenWeek[i].Link);
            3: arrTmp2[i,x].HTMLText.add(arrOpenWeek[i].RawTitle);
            4: arrTmp2[i,x].HTMLText.add(arrOpenWeek[i].RawPlayers);
            5: arrTmp2[i,x].HTMLText.add(arrOpenWeek[i].RawPlot);
            6: arrTmp2[i,x].HTMLText.add(arrOpenWeek[i].RawBuzz);
          end;
        end;
      end;
      { WRITE THE OBJECTS INTO THE STREAM }
      for i := 0 to high(arrTmp2) do
        for x := 0 to 6 do
          F.WriteComponent(arrTmp2[i,x])
    finally
      { DELETE TEMP OBJECTS }
      for i := 0 to high(arrTmp2) do
        for x := 0 to 6 do
          arrTmp2[i,x].free;
    end;
  finally
    F.Free;
  end;
end;

procedure ReadObjects();
var
  count, i, x: integer;
begin
  CurDir := ExtractFileDir(Application.ExeName);
  if FileExists(CurDir + '\results.dat') then begin
    F := TFileStream.Create(CurDir + '\results.dat', fmOpenRead or fmShareDenyWrite);
    try
      F.ReadComponent(HTMLTreeview1);
      F.ReadComponent(HTMLTreeview2);
      F.ReadComponent(HTMLabel1);
      F.ReadComponent(HTMLabel2);
      F.Read(count,1) ;
      { LOAD DYNAMIC ARRAY NOW }
      SetLength(arrTmp2, count);
      try
        { CREATE TEMP OBJECTS TO STORE THE STRINGS }
        for i := 0 to high(arrOpenWeek) do
          for x := 0 to 6 do
            arrTmp2[i,x] := THTMLabel.Create(nil);
        { READ THE OBJECT INTO THE TEMP OBJECT }
        for i := 0 to high(arrTmp2) do
          for x := 0 to 6 do
            F.ReadComponent(arrTmp2[i,x])  { <- ERROR OCCURS HERE!!}
      finally
      { DELETE TEMP OBJECTS }
        for i := 0 to high(arrTmp2) do
          for x := 0 to 6 do
            arrTmp2[i,x].free;
      end;
    finally
      f.Free;
    end;
  end;
end;

--------------------------------------------------
There are no problems saving the objects, just reading them.
The error always shows up when I -> F.ReadComponent(arrTmp2[i,x])
EReadError "Invalid stream format"

Like I said, the 1st prj code works, but not the 2nd.
And the only real difference between them is the use of a multi-dimensional array and a record.

thanx for any help
0
Comment
Question by:LMuadDIb
  • 2
3 Comments
 
LVL 34

Accepted Solution

by:
Slick812 earned 800 total points
ID: 11817207
hello  LMuadDIb, I do not have time right now to get your code and run it, to see what is problem, , but from looking at it, I can see something that I know would not work for me in code that I have written for file stream reads, , , your line -

F.Read(count,1) ;

is NOT CORRECT

should it be

F.Read(count,4) ; // count is integer, which is 32 bits (4 bytes)

or more better

F.Read(count, SizeOf(count)) ;

you might add a line to test the value

F.Read(count, SizeOf(count)) ;
if count <> 6 then ShowMessage('Not Six');
0
 
LVL 34

Expert Comment

by:Slick812
ID: 11817215
also, here is the addy for a web page which has some info about reading and writting to a TFileStream for delphi

http://www.angelfire.com/hi5/delphizeus/customfiles.html
0
 
LVL 4

Author Comment

by:LMuadDIb
ID: 11817768
thanx  for the help Slick812 :)
and nice link too
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses

916 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