Thanks for the replies. However, I'm having issues even with step 0: is there any way to even just load it in as an array or string of 1s and 0s?
How do I read in a binary file that has a very unique data structure?
조회 수: 27 (최근 30일)
이전 댓글 표시
I have a binary file of which I know the structure (i.e. A x uint16, B x 12-bit unsigned, C x uint16 etc.). I suspect I have to use "memmapfile" in some capacity to map and then read the file into a usable form but I haven't had any success after some time trying. If anyone has any ideas how one can "Read this file where bits 1 to A are uint16, A+1 to B are 12-bit unsigned, etc." that'd be a huge help. Many thanks!
댓글 수: 3
답변 (3개)
dpb
2016년 3월 30일
There's no facility in memmapfile to handle arbitrary bit-lengths; you'll have to map the 12-byte type to an array of 3-x-uint8 and then combine those results.
You also need to know endianness of the underlying data as well to interpret correctly; that should be provided by the application documentation that created the file.
댓글 수: 0
Walter Roberson
2016년 3월 30일
You need to know whether the "12 bit unsigned" is 12 bits out of every 16 with the other 4 ignored, or if the 12 bits are packed together, 2 of them for every 3 8-bit bytes? If they are packed together, then you need to have defined what happens if you end in the middle of a byte because B is not a multiple of 2.
댓글 수: 0
Teja Muppirala
2016년 4월 1일
Would it be possible to use FREAD with the precision specified?
For example:
%% Just making some test data... (16bit,12bit,16bit // 16bit,12bit,16bit // ...)
digitsOfPi = [3 1 4 1 5 9 2 6 5 3 5 9]
fileID = fopen('pi.dat','w');
for n = 1:numel(digitsOfPi)
switch mod(n,3)
case 1
fwrite(fileID,digitsOfPi(n),'ubit16');
case 2
fwrite(fileID,digitsOfPi(n),'ubit12');
case 0
fwrite(fileID,digitsOfPi(n),'ubit16');
end
end
fclose(fileID);
%% Now read the file back in:
fileID = fopen('pi.dat','r');
n = 0;
while ~feof(fileID)
n = n+1;
switch mod(n,3)
case 1
data = fread(fileID,1,'ubit16')
case 2
data = fread(fileID,1,'ubit12')
case 0
data = fread(fileID,1,'ubit16')
end
end
fclose(fileID);
This gives me back
data =
3
data =
1
data =
4
data =
1
data =
5
data =
9
data =
2
data =
6
data =
5
data =
3
data =
5
data =
9
data =
[]
댓글 수: 2
Walter Roberson
2016년 4월 1일
Note that each fread will start at a byte boundary and that when the count is exhausted that any partial byte unread will be discarded. It is thus not suitable for advancing through a file as if the file were a bit array.
dpb
2016년 4월 1일
Interesting! I wasn't aware there was such a thing as 'uint12' that Matlab would recognize, even. Of course, as you note the above "works" for the OP as it writes 16-bits to store 12...
>> fid=fopen('test.dat','w');
>> fwrite(fid,3,'ubit12');
>> fid=fclose(fid);
Open file in a binary mode viewer...
C:\ML_R2012b\work> ty /x test.dat
0000 0000 03 00 ♥.
shows two bytes were written so by symmetry fread read the same two bytes when used 'uint12' there as well. The demonstration shows the underlying C i/o library is consistent but doesn't, as you note, do anything for the OP if the file is actually a packed bitstream as would seem to be, probably from some lab instrument.
참고 항목
카테고리
Help Center 및 File Exchange에서 Low-Level File I/O에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!