Reputation: 2802
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
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