Matt
Matt

Reputation: 2802

Matlab return bytes from fread

I am trying to read binary data that is saved in evenly spaced blocks in a file. Each data block begins with a record header that contains variable information about reading the file. The header is always a constant size in bytes. I then read the header data to determine what's in the data block and how to read it. For most data blocks the majority of the header is unused. In python it looks like this:

headerBytes = in_file.read(rSize)
aCode = unpack('1i', headerBytes[0:4])
bCode = unpack('1i', headerBytes[4:8])
....
subcase = unpack(str(len(headerBytes[aCode:bCode]))+'s',headerBytes[aCode:bCode])

I can do something similar in C++ with reinterpretcast on a character array read from the binary file. As you can see the information stored in the header is dependent on previous information in the header itself.

In Matlab I am struggling with fread and reading in the entire header and then processing it. The problem is that I haven't found a good way to return the bytes to be post-processed later. The best I have is something like this:

aCode = fread(fid, 1, 'int');
bCode = fread(fid, 1, 'int');
.... <Conditional statements including fread, fseek, etc to further process
subcase = fread(fid, bCode - aCode, 'char');

This is very slow compared to the python and C++ ways of reading the entire header at once. I tried using typecase like this:

header = fread(fid, 584, 'char');
aCode = typecast(header(1:4), 'int32');

This fails by producing not a single number but rather a vector of size 8x1. How can a chunk of binary data (bytes) be read and returned in Matlab like in Python and C++?

Upvotes: 0

Views: 518

Answers (1)

Cris Luengo
Cris Luengo

Reputation: 60680

Your issue is because you are reading the bytes and casting them to doubles in your fread statement. So header(1:4) is 4 doubles, which cast to int32 gives you 8 values.

The correct way of reading in the data is

header = fread(fid, 584, '*uint8');

The * in the type indicates that the output array should be of the same type. It is equivalent to 'uint8=>uint8'. 'uint8', by itself, is equivalent to 'uint8=>double'. The type after the => part is the type of the output array.

You can use uchar instead of uint8 if you like, though I prefer to stay away from char types as sometimes they are 16 bytes.

See this section of the fread documentation for more information.

Upvotes: 1

Related Questions