What is best way to read and interpret binary files?

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Nov 19 22:32:55 UTC 2018


On Mon, Nov 19, 2018 at 10:14:25PM +0000, Neia Neutuladh via Digitalmars-d-learn wrote:
> On Mon, 19 Nov 2018 21:30:36 +0000, welkam wrote:
> > So my question is in subject/title. I want to parse binary file into D
> > structs and cant really find any good way of doing it. What I try to do
> > now is something like this
> > 
> > byte[4] fake_integer;
> > auto fd = File("binary.data", "r");
> > fd.rawRead(fake_integer);
> > int real_integer = *(cast(int*)  fake_integer.ptr);
> > 
> > What I ideally want is to have some kind of c style array and just cast
> > it into struct or take existing struct and populate fields one by one
> > with data from file. Is there a D way of doing it or should I call
> > core.stdc.stdio functions instead?
> 
> Nothing stops you from writing:
> 
>     SomeStruct myStruct;
>     fd.rawRead((cast(ubyte*)&myStruct)[0..SomeStruct.sizeof]);

Actually, the case is unnecessary, because arrays implicitly convert to
void[], and pointers are sliceable.  So all you need is:

	SomeStruct myStruct;
	fd.rawRead((&myStruct)[0 .. 1]);

This works for all POD types.

Writing the struct out to file is the same thing:

	SomeStruct myStruct;
	fd.rawWrite((&myStruct)[0 .. 1]);

with the nice symmetry that you just have to rename rawRead to rawWrite.

For arrays:

	SomeStruct[] arr;
	fd.rawWrite(arr);
	...

	arr.length = ... /* expected length */
	fd.rawRead(arr);

To correctly store length information, you'll have to manually write out
array lengths as well, and read it before reading the array. Should be
straightforward to figure out.


> Standard caveats about byte order and alignment.

Alignment shouldn't be a problem, since local variables should already
be properly aligned.

Endianness, however, will be a problem if you intend to transport this
data to/from a different platform / hardware.  You'll need to manually
fix the endianness yourself.


T

-- 
This is not a sentence.


More information about the Digitalmars-d-learn mailing list