Solved

WriteComponent & ReadComponent with dynamic object arrays...

Posted on 2004-08-16
3
617 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 33

Accepted Solution

by:
Slick812 earned 200 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 33

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
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…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

920 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

15 Experts available now in Live!

Get 1:1 Help Now