Board index » delphi » D3 to D5 file read problem

D3 to D5 file read problem

Hi.

I'm porting an application from Delphi 3 to Delphi 5 and hit a problem
when reading files written with the D3 version of my application.

Here's a simplified example of what seems to be the root cause of the
problems I'm having:

type

  stringz255=array[0..255] of char;

  TtestData=record
    myDate:TDateTime;
    myString25:string25;
    myNotes:stringz255
  end;

var
  testData:TtestData;
  testDataFile:file of TtestData;

Files of type testDataFile have been written to disk using Delphi 3.

When the files are read using Delphi 5, I get a "Read beyond end of
file" error.

Any ideas?

--
Gary Jones

 

Re:D3 to D5 file read problem


In article <397b3af7.52636...@News.Dial.Pipex.Com>, Mike
<pb56DEL...@dial.pipex.com> writes

Quote
>Don't be offended but the naming of your variables could be better

Those variable names were only used to illustrate the problem.

Quote
>The type declaration should look something like this:

The illustrative data structure I gave you works fine in Delphi 3
(writing and reading). My problem is reading the data structure in
Delphi 5. The use of null terminated strings is deliberate.

Quote
>The routine below is just a demo for reading the file
>  path1 should hold the complete pathname of the file.

This is bog-standard file-reading which I do already (apart from the
while not eof loop which isn't relevant since there's only one record
per file).

--
Gary Jones

Re:D3 to D5 file read problem


In article <Jf0aoCA3owe5E...@bohr.demon.co.uk>, Gary Jones
<newsmas...@bohr.demon.co.uk> writes

Quote

>  TtestData=record
>    myDate:TDateTime;
>    myString25:string25;
>    myNotes:stringz255
>  end;

In my original post, I missed out the type declaration

  string25=string[25];

Equivalently, the illustrative data structure should have read:

  TtestData=record
    myDate:TDateTime;
    myString25:string[25];  {this one changed}
    myNotes:stringz255
  end;

Sorry about that.

Anyway, still hoping for some clues as to what's going on.

--
Gary Jones

Re:D3 to D5 file read problem


JRS:  In article <Jf0aoCA3owe5E...@bohr.demon.co.uk> of Sun, 23 Jul 2000
16:07:35 seen in news:alt.comp.lang.borland-delphi, Gary Jones

Quote
<newsmas...@bohr.demon.co.uk> wrote:
>I'm porting an application from Delphi 3 to Delphi 5 and hit a problem
>when reading files written with the D3 version of my application.
>  TtestData=record
>Files of type testDataFile have been written to disk using Delphi 3.

>When the files are read using Delphi 5, I get a "Read beyond end of
>file" error.

It seems very likely that the records are differently padded - see
"packed record" in the manual, maybe.

The solution is probably to make the record packed in D5, and to pad it
by hand to D3 standard.

The right way to do it is to use packed records in both D3 & D5.

It is possible that one or more of your types have changed actual size
(though I think not) -  Web <URL: http://www.merlyn.demon.co.uk/pas-
type.htm>  may help (and you may be able to fill in some "?").

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
 <URL: http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
 <URL: ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ;
 <URL: http://www.merlyn.demon.co.uk/clpb-faq.txt> Pedt Scragg: c.l.p.b. mFAQ.

Re:D3 to D5 file read problem


Quote
> I'm porting an application from Delphi 3 to Delphi 5 and hit a problem
> when reading files written with the D3 version of my application.

> Here's a simplified example of what seems to be the root cause of the
> problems I'm having:
>  .....
> Files of type testDataFile have been written to disk using Delphi 3.

> When the files are read using Delphi 5, I get a "Read beyond end of
> file" error.

If you still have Delphi 3 try to check size of each element of record, both
in Delphi3 and Delphi5, eg:

sizeof(TTestData.myDate)
sizeof(TTestData.myString25)
sizeof(TTestData.stringz255)

If they don't equal, problem is in different type declaration of types in
versions of Delphi, you will have workaround it somehow.

If they equals, problem is probably in word alignment, see
Project/Options/Compiler/Aligned record fields (in Delphi 5)

Sorry for my bad English.

--
Martin Prikryl
xpri...@vse.cz
http://sorry.vse.cz/~xprim14

Re:D3 to D5 file read problem


Thanks to John and Martin.

The problem is definitely due to this packed record business.

I ran a test on my test data structure:

type
  string25=string[25];
  stringz255=array[0..255] of char;

  TtestData=record
    myDate:TDateTime;
    myString25:string25;
    myNotes:stringz255
  end;

and also a packed version of the same:

  TpackedTestData=packed record
    myDate:TDateTime;
    myString25:string25;
    myNotes:stringz255
  end;

I compiled and ran tests in D3 and D5 and here are the results:

{best viewed in a non-proportional font}

               DELPHI 3           DELPHI 3
              Not packed           Packed
         (as my application)
             size  offset        size  offset

myDate          8     0             8     0
myString25     26     8            26     8
myNotes       256    34           256    34

whole record  292                 290

               DELPHI 5           DELPHI 5
              Not packed           Packed
             size  offset        size  offset

myDate          8     0             8     0
myString25     26     8            26     8
myNotes       256    34           256    34

whole record  296                 290

So D5 is trying to read 296 bytes, but the record is only 292 bytes
long. {*word*81}.

So what to do?

The option of using packed record in D5 and inserting padding bytes
where needed seems the only likely possibility, but it seems a bit of a
pain.

I used code such as the following...
integer(@testData.myDate)-Integer(@testData)
... to generate the offset figures above, but they are all the same, so
I can't see how to begin figuring out where to put my padding bytes. Is
this code right, or is there some other way of determining what the
offsets for each element in the record?

With the clues you've given I could refine my search in deja.com and I
found a post that suggested that the problem is in data items of type
double (such as TDateTime) but according to the D3 and D5 documentation,
the alignment for this data items doesn't seem to have changed.

Bearing in mind that in the real application the record contains
hundreds of data items, I need a clue how to attack it.

Thanks for the help so far.

--
Gary Jones

Re:D3 to D5 file read problem


  I had the same problem upgrading from Delphi 4 to Delphi 5.
  I was using sizeof() to read records from a BLOB field. In both Delphi 4
and Delphi 5, the sum of the sizeof() of all elements of the record were
34. The sizeof() of the record was 36 and using Delphi 5, sizeof() of
the same record was 40. So, the actual size of the record insn't the sum
of the sizeof() of all its elements (unless it is a packed record) because
the
elements of the record are aligned on word or double-word. And it seems
that the aligning of the values in the record changed from Delphi 4 to
Delphi 5,
but this is just a guess.
  The solution may be using a TFileStream to read the file, so you can read
any amount of data using the TFileStream.Read method.

Martin Prikryl <martin.prik...@seznam.cz> escreveu nas notcias de
mensagem:8lgv7e$gp...@vse470.vse.cz...

Quote
> > I'm porting an application from Delphi 3 to Delphi 5 and hit a problem
> > when reading files written with the D3 version of my application.

> > Here's a simplified example of what seems to be the root cause of the
> > problems I'm having:
> >  .....
> > Files of type testDataFile have been written to disk using Delphi 3.

> > When the files are read using Delphi 5, I get a "Read beyond end of
> > file" error.

> If you still have Delphi 3 try to check size of each element of record,
both
> in Delphi3 and Delphi5, eg:

> sizeof(TTestData.myDate)
> sizeof(TTestData.myString25)
> sizeof(TTestData.stringz255)

> If they don't equal, problem is in different type declaration of types in
> versions of Delphi, you will have workaround it somehow.

> If they equals, problem is probably in word alignment, see
> Project/Options/Compiler/Aligned record fields (in Delphi 5)

> Sorry for my bad English.

> --
> Martin Prikryl
> xpri...@vse.cz
> http://sorry.vse.cz/~xprim14

Re:D3 to D5 file read problem


JRS:  In article <HXZZ6BAEmIf5E...@bohr.demon.co.uk> of Mon, 24 Jul 2000
19:23:00 seen in news:alt.comp.lang.borland-delphi, Gary Jones

Quote
<newsmas...@bohr.demon.co.uk> wrote:

>Bearing in mind that in the real application the record contains
>hundreds of data items, I need a clue how to attack it.

Remember that you may need to pad after any item in the record,
including the last.

Construct a test program, console mode, DCC32 -cc  :
type T = <complicated-record-containing-fields-A,B,C,D,...> ;
Z : array [0..pred(sizeof(T))] ;
var X : T ;
begin
  fillchar(X, Sizeof(X), 0) ;
  fillchar(X.B, SizeOf(X.B), 1) ;
  for J := 1 to .. do if Z(X)[J]>Z(X)[J-1] then writeln(J:6) ;
  end.

Run this in D3 with your exact D3 type definition.
Then run in D5 and adjust the padding before immediately B to get B in
the right place.

Repeat for C, D, ...; then pad the end to get SizeOf right.

You will need the same amount of padding after each occurrence of any
given type, so prediction should be possible.

It may be safest to use one program for D3, D5, using
        {$IFDEF VERxx} packed {$ENDIF)
        {$IFDEF VERxx} pad1, pad2:byte; {$ENDIF)
for insertions.

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
 Web <URL: http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
 Proper 4-line sig. separator is as above, a line exactly "-- " (SonOfRFC1036)
 Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)

Re:D3 to D5 file read problem


Thanks for the help.

It seem that the easiest solution might be to write a utility in D3 to
update each file on disk by converting its unpacked record (and its
unpacked nested records) to packed records and writing an updated file
to the disk. Then, using packed records in D5, I should be able to read
the files.

But... unpacked records are the default and are structured to make CPU
access more efficient. Is moving to packed records likely to cause any
problems in performance or stability?

--
Gary Jones

Other Threads