### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

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

#### speter

• New Member
• Posts: 40
##### (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 »

#### speter

• New Member
• Posts: 40
##### 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]]);
55.     end;
56.
57.   assignfile(f,'foo.dat');
58.   rewrite(f);
59.   write(f,d);
60.   closefile(f);
62. end;

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

#### Handoko

• Hero Member
• Posts: 3912
• 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

• New Member
• Posts: 40
##### 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.

#### ASerge

• Hero Member
• Posts: 1693
##### 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

• New Member
• Posts: 40
##### Re: (Solved) creating a binary fiile
« Reply #5 on: October 14, 2020, 12:24:54 am »

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.

#### jamie

• Hero Member
• Posts: 3797
##### 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

• New Member
• Posts: 40
##### Re: (Solved) creating a binary fiile
« Reply #7 on: October 15, 2020, 07:44:12 am »