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 commentaire

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);

Connectez-vous pour commenter.

 Réponse acceptée

Guillaume
Guillaume le 7 Juil 2017
Modifié(e) : Guillaume le 8 Juil 2017
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 commentaires

Walter Roberson
Walter Roberson le 7 Juil 2017
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 le 7 Juil 2017
Modifié(e) : Guillaume le 7 Juil 2017
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 le 8 Juil 2017
Modifié(e) : Guillaume le 8 Juil 2017
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 le 9 Juil 2017
Modifié(e) : Guillaume le 10 Juil 2017
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');
Walter Roberson
Walter Roberson le 9 Juil 2017
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.

Connectez-vous pour commenter.

Plus de réponses (1)

Walter Roberson
Walter Roberson le 7 Juil 2017

0 votes

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

Catégories

En savoir plus sur Large Files and Big Data dans Centre d'aide et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by