Hi! I have a binary file. It consists of records: 8 byte long, 4 byte float, 4 byte float, 4 byte float. I want to read the file into array Nx4. N - records number. How can I do it? I tried fread but without result.

댓글 수: 1

Is it correct?
fid = fopen('acc-angle.bin', 'rb'); % открытие файла на чтение
if fid == -1 % проверка корректности открытия
error('File is not opened');
end
time=[];
ax=[];
ay=[];
az=[];
records_num=0;
while ~feof(fid)
time = [time; fread(fid,1,'int64')];
ax= [ax; fread(fid,1,'float32')];
ay= [ay; fread(fid,1,'float32')];
az= [az; fread(fid,1,'float32')];
records_num=records_num+1;
end
fclose(fid);

댓글을 달려면 로그인하십시오.

 채택된 답변

Guillaume
Guillaume 2017년 7월 7일
편집: Guillaume 2017년 7월 8일

2 개 추천

Is it correct? The easiest way for you to find out is to try.
fid = fopen('acc-angle.bin', 'rb')
There's no 'b' option for fopen permissions. 'r' is all that is needed for binary.
Otherwise, your code looks ok to me as long as your file has little endian encoding. A faster option would be to read all records at once using the skip parameter of fread, something like:
fid = fopen('acc-angle.bin', 'r');
time = fread(fid, Inf, 'int64', 12);
fseek(fid, 'bof', 8);
ax = fread(fid, Inf, 'single', 16);
fseek(fid, 'bof', 12);
ay = fread(fid, Inf, 'single', 16);
fseek(fid, 'bof', 16);
az = fread(fid, Inf, 'single', 16);
fclose(fid);

댓글 수: 7

After each of those fread() you should fseek() to beginning of file offset by the sum of the sizes of all of the previous fields. That is, after each fread() you are left at end of file and need to reposition.
Guillaume
Guillaume 2017년 7월 7일
편집: Guillaume 2017년 7월 7일
Oops! Yes, of course. Fixed.
If the file is large, I've found that multiple calls to fread is (order of magnitude) slowers than reading the whole file all in one go, even when these calls are just reading one value after another without any seeking.
Thanks a lot! But one mistake: In the last three lines 16 instead of 12. Am I right?
time = fread(fid, Inf, 'int64', 12);
fseek(fid, 8, 'bof');
ax = fread(fid, Inf, 'single', 16);
fseek(fid, 12, 'bof');
ay = fread(fid, Inf, 'single', 16);
fseek(fid, 16, 'bof');
az = fread(fid, Inf, 'single', 16);
Guillaume
Guillaume 2017년 7월 8일
편집: Guillaume 2017년 7월 8일
Yes! Fixed as well.
It revealed, that I have to invert byte order for each field before reading. How can I do this?
Guillaume
Guillaume 2017년 7월 9일
편집: Guillaume 2017년 7월 10일
If it's the same for the whole file, in the call to fopen:
fid = fopen('acc-angle.bin', 'r', 'b'); %b for big endian
If it varies per field, in the call to fread:
time = fread(fid, Inf, 'int64', 12, 'b');
At the time you do the fopen() you can specify a byte order that is to apply by default to future fread().
Or, for each fread() you can specify the byte order.
Or, you can swapbytes() after doing the reading.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Walter Roberson
Walter Roberson 2017년 7월 7일

0 개 추천

memmapfile allows you to declare patterns of fields and so is suitable for reading in repeated structures.

카테고리

도움말 센터File Exchange에서 Low-Level File I/O에 대해 자세히 알아보기

질문:

2017년 7월 7일

편집:

2017년 7월 10일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by