Recent

Author Topic: (Solved) creating a binary fiile  (Read 1385 times)

speter

  • Sr. Member
  • ****
  • Posts: 349
(Solved) creating a binary fiile
« on: October 13, 2020, 08:36:21 am »
G'Day Folks,

I am trying to create a program to create a binary file.

The structure of the file is:
  1 x 32bit integer; then
  100 x 32bit single.

My original thought was to go for a "file of byte"; but I'm not sure how to write the integer or the reals as bytes (that is I'm not sure whether it would be hi-bit first (or last)).

The first integer gives the size of the remaining data; in this case it will be "10" (the data is 10x10)...

Any suggestions!?

Can I (simply) do something like:
Code: Pascal  [Select][+][-]
  1. assignfile(f,'foo.dat');
  2. rewrite(f);
  3. write(f,size);
  4. for a := 0 to 99 do write(f,d[a]);
  5. closefile(f);

The other thing I am unsure about is making sure I write 32bit info...

cheers
S.
« Last Edit: October 13, 2020, 09:18:05 am by speter »
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

speter

  • Sr. Member
  • ****
  • Posts: 349
Re: creating a binary fiile
« Reply #1 on: October 13, 2020, 09:16:30 am »
Further to the above :)

included below is a first attempt using an example @
https://wiki.freepascal.org/typed_files (File handling "typed files")
section = Write Data Record.

My code is:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. const
  3.   sz = 9;
  4. type
  5.   dtype = record
  6.             size : integer;
  7.             data : array [0..sz,0..sz] of single;
  8.           end;
  9. var
  10.   d : dtype;
  11.  
  12.   procedure around(x,y : byte);
  13.   var
  14.     a,b, kx,ky : integer;
  15.   begin
  16.     for a := -1 to 1 do
  17.       begin
  18.         ky := y + a;
  19.         if (ky in [0..sz]) then
  20.           for b := -1 to 1 do
  21.             begin
  22.               kx := x + b;
  23.               if (kx in [0..sz]) then
  24.                 if d.data[kx,ky] = 0 then
  25.                   d.data[kx,ky] := min(1.0,max(0.0,d.data[x,y] + (random / 5) - 0.1));
  26.             end;
  27.       end;
  28.   end;
  29.  
  30. var
  31.   a, x,y : byte;
  32.   f : file of dtype;
  33.   s : string;
  34. begin
  35.   randomize;
  36.   d.size := sz+1;
  37.  
  38.   for y := 0 to sz do
  39.     for x := 0 to sz do
  40.       d.data[x,y] := 0;
  41.  
  42.   d.data[random(10),random(10)] := random;
  43.  
  44.   for a := 0 to 19 do
  45.     for y := 0 to sz do
  46.       for x := 0 to sz do
  47.         if d.data[x,y] > 0 then around(x,y);
  48.  
  49.   for y := 0 to sz do
  50.     begin
  51.       s := '';
  52.       for x := 0 to sz do
  53.         s := s + format(' %5.3f',[d.data[x,y]]);
  54.       memo1.lines.add(y.tostring+':'+s);
  55.     end;
  56.  
  57.   assignfile(f,'foo.dat');
  58.   rewrite(f);
  59.   write(f,d);
  60.   closefile(f);
  61.   memo1.lines.add('"foo.dat" created.');
  62. end;

The file is 404 bytes, 101 x 4 bytes, so I guess it is correct!

I climbed mighty mountains, and saw that they were actually tiny foothills. :)

Handoko

  • Hero Member
  • *****
  • Posts: 5153
  • My goal: build my own game engine using Lazarus
Re: (Solved) creating a binary fiile
« Reply #2 on: October 13, 2020, 09:23:52 am »
Alternatively you can convert Integer or Single to 4-bytes array by using combination of Pointer and absolute:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. type
  3.   T4Bytes = array[0..3] of Byte;
  4. var
  5.   PLongInt: ^LongInt; // Use LongInt to make sure it is a 4-bytes Integer
  6.   P4Bytes:  ^T4Bytes absolute PLongInt; // Use absolute to point it to PLongInt
  7.   Test:     LongInt;
  8.   i:        Integer;
  9. begin
  10.   Test := 1; // Put some value here for testing
  11.   PLongInt := @Test;
  12.   for i := 0 to 3 do
  13.     ShowMessage(IntToStr(P4Bytes^[i])); // P4Byte^[0..3] has the data of Test
  14. end;

speter

  • Sr. Member
  • ****
  • Posts: 349
Re: (Solved) creating a binary fiile
« Reply #3 on: October 13, 2020, 01:55:35 pm »
Thanks very much for answering Handoko.

The file-of-record approach worked for me and is nice and simple. :)

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

ASerge

  • Hero Member
  • *****
  • Posts: 2241
Re: (Solved) creating a binary fiile
« Reply #4 on: October 13, 2020, 05:34:01 pm »
The file-of-record approach worked for me and is nice and simple. :)
For file IO operations, it is better always declare record with the packed prefix, and explicitly specify the size types. This will help you avoid problems in the future.
In this case, you are lucky, because the size of the Single type is no larger than the size of the Integer type. For example, if you take the Double type instead of the Single type, the size will not be 4 + 8*100, but 8 + 8*100 (on Windows platform).
For greater clarity, it is better to write packed even for arrays, although this is already implied:
Code: Pascal  [Select][+][-]
  1. type
  2.   DataType = packed record
  3.     Size: Int32;
  4.     Data: packed array[0..99] of Single;
  5.   end;

speter

  • Sr. Member
  • ****
  • Posts: 349
Re: (Solved) creating a binary fiile
« Reply #5 on: October 14, 2020, 12:24:54 am »
Thanks for the reply, ASerge.

Is it possible to explicitly declare a 32-bit real type?
I know that 'single' _is_ a 32-bit type, but (for example) 'int32' is explicitly so.
The docs (https://www.freepascal.org/docs-html/ref/refsu5.html) don't include a real type "named" as 32-bit.

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: (Solved) creating a binary fiile
« Reply #6 on: October 14, 2020, 01:25:51 pm »
a single is a 32 bit real number as pointed out..

if you want to makeup some fancy new name to it... you can do this..

Type
   My32BitReal = single;

and from there on the compiler will just use single in place of your type..

and for what @ASerge pointed out was just a define in the libs basically done the same way

 Int32 = longint;

Did I miss something ?
 
The only true wisdom is knowing you know nothing

speter

  • Sr. Member
  • ****
  • Posts: 349
Re: (Solved) creating a binary fiile
« Reply #7 on: October 15, 2020, 07:44:12 am »
Thanks for the reply Jamie.

I was really thinking about what might happen in the future...

I don't think "int32" will ever stop being 32-bit; but conceivably "single" could one day become 64-bit floating number... but I guess lots of programs would stop working... so it probably will not happen. :)

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

 

TinyPortal © 2005-2018