fread: how to read n bytes from bin files

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 comentario

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

Iniciar sesión para comentar.

 Respuesta aceptada

Guillaume
Guillaume el 7 de Jul. de 2017
Editada: Guillaume el 8 de Jul. de 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 comentarios

Walter Roberson
Walter Roberson el 7 de Jul. de 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 el 7 de Jul. de 2017
Editada: Guillaume el 7 de Jul. de 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 el 8 de Jul. de 2017
Editada: Guillaume el 8 de Jul. de 2017
Yes! Fixed as well.
Alexander Voznesensky
Alexander Voznesensky el 9 de Jul. de 2017
It revealed, that I have to invert byte order for each field before reading. How can I do this?
Guillaume
Guillaume el 9 de Jul. de 2017
Editada: Guillaume el 10 de Jul. de 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 el 9 de Jul. de 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.

Iniciar sesión para comentar.

Más respuestas (1)

Walter Roberson
Walter Roberson el 7 de Jul. de 2017

0 votos

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

Categorías

Etiquetas

Preguntada:

el 7 de Jul. de 2017

Editada:

el 10 de Jul. de 2017

Community Treasure Hunt

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

Start Hunting!

Translated by