Recent

Author Topic: Tfilestream sizeof and position  (Read 5867 times)

frederic

  • Full Member
  • ***
  • Posts: 226
Tfilestream sizeof and position
« on: August 18, 2017, 11:28:44 am »
dear specialist
a basic question :
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var  xtempfilenaam:string;
  3.     dateint,timeint,Aint,Bint,Cint,Dint,Eint:integer;
  4.     xFileStream1: TFileStream;
  5.     p1,p2,p3,p4,p5,p6,p7:int64;
  6. begin
  7.         dateint:=39000;
  8.        timeint:=900;
  9.         Aint:=25;Bint:=12;Cint:=150;Dint:=2290;Eint:=35000000;
  10.  
  11.         xtempfilenaam:= 'c:\users\public\STEPBYSTEPFILETESTFOLDERS\testname200';
  12.         xFileStream1 := TFileStream.Create(xtempfilenaam,
  13.                 fmCreate or fmOpenWrite or fmShareDenyWrite);
  14.  
  15.          xFileStream1.WriteBuffer(dateint, SizeOf(dateint));
  16.          p1 :=xFileStream1.position;
  17.          xFileStream1.WriteBuffer(timeint, SizeOf(timeint));
  18.          p2:=xFileStream1.position;
  19.          xFileStream1.WriteBuffer(Aint, SizeOf(Aint));
  20.          p3:= xFileStream1.position;
  21.          xFileStream1.WriteBuffer(Bint, SizeOf(Bint));
  22.          p4:= xFileStream1.position;
  23.          xFileStream1.WriteBuffer(Cint, SizeOf(Cint));
  24.          p5:= xFileStream1.position;
  25.          xFileStream1.WriteBuffer(Dint, SizeOf(Dint));
  26.          p6:= xFileStream1.position;
  27.          xFileStream1.WriteBuffer(Eint, SizeOf(Eint));
  28.          p7:= xFileStream1.position;
  29.          memo1.lines.add('p1= '+inttostr(p1)+ 'p2= '+inttostr(p2)+'p3= '+inttostr(p3)+'p4= '+inttostr(p4)+'p5= '+inttostr(p5) +'p6= '+inttostr(p6)+'p7= '+inttostr(p7));
  30.          memo1.lines.add( ' size of filestream = '+ inttostr(sizeof(xFileStream1)));
  31.  
  32.  
  33.  
  34. end;              
when you runn this the p1..p7 steps up with 4 bytes each mounting to 28.
The size of the filestream is returning  4 .I would have expected :28

why is this?
frederic
« Last Edit: August 18, 2017, 11:32:22 am by frederic »

Noodly

  • Jr. Member
  • **
  • Posts: 70
Re: Tfilestream sizeof and position
« Reply #1 on: August 18, 2017, 11:47:34 am »
Change the last line to:

Code: [Select]
memo1.lines.add( ' size of filestream = '+ inttostr(xFileStream1.Size));
Your original code is returning the size of the pointer to the xFileStream1 object, instead it should be calling the TFileStream.Size method.
Windows 10 Home, Lazarus 2.02 (svn 60954), FPC 3.04

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Tfilestream sizeof and position
« Reply #2 on: August 18, 2017, 11:48:11 am »
xFilestream1 is a reference to a class, it is a pointer. On 32-bit systems it has a size of 4, 8 on 64-bit systems.

This is different from xFileStream1.Size, which reports the length of the stream.

frederic

  • Full Member
  • ***
  • Posts: 226
Re: Tfilestream sizeof and position
« Reply #3 on: August 18, 2017, 02:50:31 pm »
thanks howard and noodly

Quote
xFilestream1 is a reference to a class, it is a pointer. On 32-bit systems it has a size of 4, 8 on 64-bit systems.

i hope the amount of bytes for each integer remains 4.

the reason why am asking this is that i want to make a standard filestreamfile per day .
in this file we wil have standard ,say 500 minutes  , and for each minute say 50 indicators.
 All the values are in integer.

so when i need to change in minute x ,indicator  no 10 . then i can can calculate its position in the file  X*50*4 +10*4 

Code: Pascal  [Select][+][-]
  1. xFileStream1 := TFileStream.Create( xtempfilenaam, fmOpenReadWrite or fmShareExclusive)
  2.          xFileStream1.position:=  X*50*4 +10*4  ;
  3.          xFileStream1.readBuffer(INDIC10, SizeOf(INDIC10));
  4.          INDIC10:= newvalue1;
  5.          xFileStream1.writeBuffer(INDIC10, SizeOf(INDIC10));
  6.          xFileStream1.position:=  Y*50*4 +20*4  ;
  7.          xFileStream1.readBuffer(INDIC20, SizeOf(INDIC20));
  8.          INDIC20:= newvalue2;
  9.          xFileStream1.writeBuffer(INDIC20, SizeOf(INDIC20));
  10.           xFileStream1. free;              

as you can see it is based on 4 bytes per integer, when that changes i have to do something different

the idea is to eliminate the neccesity to keep large arrays  and now only cherry-pick the values you need(or need to change)

frederic

Mick

  • Jr. Member
  • **
  • Posts: 51
Re: Tfilestream sizeof and position
« Reply #4 on: August 18, 2017, 03:11:11 pm »
To be sure that you will operate with 4 bytes to store that number persisted in a stream, maybe it is better to use LongInt instead. LongInt is always 32bit / 4 byte, in contrast to Integer which can be 16bit / 2 bytes on some platforms. This way your storage format will be independent of $MODE compiler switch. Maybe you should also think about big-endian / little-endian marker somewhere at the beginning of your stream to tell the readers of that stream how should they interpret the values read from stream (and apply byte-swapping if needed).

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Tfilestream sizeof and position
« Reply #5 on: August 18, 2017, 03:22:27 pm »
Or instead of using the hardcoded number 4, simply use SizeOf(Integer) everywhere you need it. This would cater for running your app on platforms where the size of an Integer is not 4. There is no performance penalty for using SizeOf(). The compiler inserts the correct constant value for you at compile time.

frederic

  • Full Member
  • ***
  • Posts: 226
Re: Tfilestream sizeof and position
« Reply #6 on: August 18, 2017, 03:29:04 pm »
thnks for the tips

frederic

Mick

  • Jr. Member
  • **
  • Posts: 51
Re: Tfilestream sizeof and position
« Reply #7 on: August 18, 2017, 03:31:37 pm »
@howardpc - The problem with SizeOf(Integer) is that it can be different depending on the platform. Imagine you have a file that was saved using this code compiled with 32bit / 4 bytes Integer. After that you have decided to support other platform (where Integer type is 16bit / 2 bytes) and you are using the same codebase.
For these reasons the usage of LongInt and SizeOf(Longint) is better.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Tfilestream sizeof and position
« Reply #8 on: August 18, 2017, 04:59:30 pm »
Point taken. The problem only arises if you use the same code on incompatible platforms, and also try to read a datafile from the 'wrong' platform.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1314
    • Lebeau Software
Re: Tfilestream sizeof and position
« Reply #9 on: August 22, 2017, 03:36:05 am »
To be sure that you will operate with 4 bytes to store that number persisted in a stream, maybe it is better to use LongInt instead. LongInt is always 32bit / 4 byte, in contrast to Integer which can be 16bit / 2 bytes on some platforms.

That is not the case in Delphi.  It is actually the reverse.  Longint is 4 bytes on most platforms, but is 8 bytes on iOS 64bit.  Whereas Integer is fixed at 4 bytes on all platforms (even though it was originally documented/intended to be a platform-dependent type).

A better idea would be to use a fixed-sized type that is not dependent on platform or implementation, such as Int32.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: Tfilestream sizeof and position
« Reply #10 on: August 23, 2017, 02:02:54 am »
Or DWORD, LONGWORD etc  ;D
The only true wisdom is knowing you know nothing

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Tfilestream sizeof and position
« Reply #11 on: August 23, 2017, 02:08:37 am »
Or DWORD, LONGWORD etc  ;D
no, let them die out, they are horrible names int16, uint32 etc are far better.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1314
    • Lebeau Software
Re: Tfilestream sizeof and position
« Reply #12 on: August 23, 2017, 02:40:22 am »
Or DWORD, LONGWORD etc  ;D

DWORD is fixed-sized (4 bytes), but LongWord is just the unsigned version of Longint, so its size is platform-dependent.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Mick

  • Jr. Member
  • **
  • Posts: 51
Re: Tfilestream sizeof and position
« Reply #13 on: August 23, 2017, 02:48:13 am »
That is not the case in Delphi.  It is actually the reverse.  Longint is 4 bytes on most platforms, but is 8 bytes on iOS 64bit.  Whereas Integer is fixed at 4 bytes on all platforms (even though it was originally documented/intended to be a platform-dependent type).

Hi Remy, I was referring to the FPC types there. I don't know what they are in the recent Delphi versions (the last version I've used was 2006, so I could not even dream about 64 bit, not to mention iOS development). But I remeber that Integer has also changed its size long time ago with switching from D2 to D3. Or was it from D1 to D2, I'm not sure? But you are right, I should take into account not only the platform switch, but also that Delphi instead of FPC/Lazarus can be used for compilation of the same codebase.

A better idea would be to use a fixed-sized type that is not dependent on platform or implementation, such as Int32.
Indeed, I wonder why these most descriptive type names were not used from the very beginning.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1314
    • Lebeau Software
Re: Tfilestream sizeof and position
« Reply #14 on: August 23, 2017, 03:02:51 am »
Hi Remy, I was referring to the FPC types there.

I know.  But it is worth mentioning Delphi behavior, since FPC models Delphi, at least in {$MODE Delphi}.

I don't know what they are in the recent Delphi versions (the last version I've used was 2006, so I could not even dream about 64 bit, not to mention iOS development).

They are as I described earlier.

But I remeber that Integer has also changed its size long time ago with switching from D2 to D3. Or was it from D1 to D2, I'm not sure?

Yes, when Delphi switched from 16-bit to 32-bit development, Integer (and Cardinal) increased in size from 2 bytes to 4 bytes.  Then, when 64-bit support was added, Integer (and Cardinal) stayed at 4 bytes (because that is the way native integers are implemented in Win64).  As more platforms have being added, new fixed-sized and variable-sized types have been introduced over time.  So now we have types like (U)IntX and Native(U)Int, and even Fixed(U)Int! (I will never understand why Embarcadero added Fixed(U)Int when (U)Int32 already existed. Fixed(U)Int is a horrible name)

I wonder why these most descriptive type names were not used from the very beginning.

There wasn't really a need for them way back then.
« Last Edit: August 23, 2017, 03:06:10 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

 

TinyPortal © 2005-2018