How can I read a binary file with mixed formats in Matlab?
Show older comments
I have a binary file with the following formats:
Column 1: char 32
Column 2: float 4
Column 3: integer 4
and I would like to read column by column in Matlab. Each column has about 700 rows of data.
I tried fid = fopen(filename,'rb');
and then used A = fread(fid,Inf,'char') to read the first column, but I've only got numeric data with many more rows than the original text. No success with the following columns either.
Thank you very much for your help.
Claude
4 Comments
Walter Roberson
on 13 Apr 2014
In your notation, does "float 4" mean a 4 byte float, or does it mean 4 repetitions of a float (each of which is 4 bytes) ?
Claude C.
on 13 Apr 2014
Walter Roberson
on 13 Apr 2014
Okay, in that case the counts that Duane used should be fine.
dpb
on 13 Apr 2014
AFAIK this or reading each field sequentially via fread is the only choice in Matlab, Walter? C could build a struct record but not implemented in Matlab.
Answers (3)
m = memmapfile('file.dat', 'Format', {'uint8, [1 32] 'chdata'; ...
'single' [1 1] 'sdata'; ...
'int32', [1 1] 'idata'});
chdata, sdata, and idata will be in named fields of the structure m.
You'll need to cast the uint8 data for the character data to character via char
doc memmapfile % for more details, of course
Image Analyst
on 13 Apr 2014
Very very easy:
t = readtable(fullFileName);
readtable can handle mixed data types on the same line. Requires R2013b and later.
5 Comments
dpb
on 13 Apr 2014
I don't have the release but from the doc's for R2014 I don't see any indication that readtable can read a binary stream file, Image.
Image Analyst
on 13 Apr 2014
Depends on what she means by binary. You're probably right though. If it's text it will work. If it's an Excel workbook (which is binary), it will figure it out and work. It it's just a big long string of undifferentiated bytes with no delimeters, then it most likely won't work because it can't figure out where the columns are separated. I haven't used memmapfile but I have used fread() to read row data and I'd probably just do something like (untested)
row = 1;
while ~feof(fid)
column1(row) = fread(fileHandle, 1, '*uint8');
column2(row) = fread(fileHandle, 1, '*single');
column3(row) = fread(fileHandle, 1, '*int32');
row = row + 1;
end
though maybe memmapfile() can do it all in one call.
dpb
on 13 Apr 2014
...though maybe memmapfile() can do it all in one call
That's its benefit/advantage in that it does it all in "one swell foop" instead of the looping construct above. Is where would be nice if Matlab would have struct to define a record a little more cleanly; never understood why not...C has it, Fortran has UDTs since F90 and many implementations the extension far earlier than that...seems like the natural extension with matrix expansion for Matlab would've been an early inclusion, but TMW never has seemed to think like I with regards to what would be the next step...nor did they ever ask. :)
Image Analyst
on 13 Apr 2014
Fair enough - I voted for yours.
Claude C.
on 15 Apr 2014
0 votes
2 Comments
Walter Roberson
on 15 Apr 2014
It will have to be 'uint8' instead of the 'uint8 accidentally given in the example.
You will probably want to add a 'Repeat', 700 option after 'Format' option.
dpb
on 15 Apr 2014
Doggone, sorry I missed the closing tick...
I'd think he'd want to map the whole file which will by default unless there are known to be precisely N records which seemed to me the "about 700" denies being either known or constant. If there's something else after these records, then that's another potential "gotcha'!", of course.
Categories
Find more on Calendar in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!