将二进制文件读入matlab

时间:2013-06-25 20:09:06

标签: matlab binary

我有一个数据文件使用(char(1字节),char [n](n个字符数组),word(2字节unsigned int),short(2字节signed int),dword(4字节unsigned int) ),long(4字节符号int)和float(4字节真实)),并且应该采用以下格式。我正在使用fopen,fread等将数据文件读入MATLAB,但我得到的值并不是我所期望的。

格式:

  • 炭[8] < - 输出拼写正确字符串标识符的8个ascii值
  • 双字 < - 数据文件的版本,msw-major版本,lsw-minor版本(尝试阅读为1 uint32和2 uint16)
  • dword
  • 双字
  • 双字
  • 双字 < - 程序中窗口显示的数量
  • displayinfo [8] < - 包含以下结构中的显示窗口参数:(不确定这是什么数据类型)
  • dword
  • 双字
  • 双字
  • 双字
  • 双字
  • 双字
  • 双字
  • 双字
  • 双字
  • 双字
  • 双字
  • 双字
  • 双字 (显示窗口参数的结尾;有些被指定为必须是[0,3]中的数字并且它们不会像那样出现)
  • 的char [16]
  • word< - 应该是年度数据被收集(2013年),但是现在是0

代码:

fid = fopen('MIC1.001','rb');
fileIdentifier = fread(fid, 8,'char');    
dataFileMajorVersion = fread(fid,1,'uint16');
dateFileMinorVersion = fread(fid,1,'uint16');
numModules = fread(fid,1,'uint32');

fread(fid,1,'uint32'); % value not used     
numSwipesCollected = fread(fid,1,'uint32');
numWindowDisplays = fread(fid,1,'uint32');
% display info vars:
displayType = [];
moduleNumber = [];
channelNumber = [];    
beginningBar = [];
endBar = [];
vertExpFactor = [];
voltageOffset =[];
isGridEnabled = [];
isEngineeringUnitEnabled = [];
colorOfDisplay = [];
multiChannelIndex = [];
numChannelsForMultiChannelDisp = [];
multiChannelDispStyle = [];

% or does it go through loop for all 8 whether or not there are 8 displays??
for i=1:numWindowDisplays 
  displayType = [fread(fid,1,'uint32'); displayType];
  moduleNumber = [fread(fid,1,'uint32'); moduleNumber];
  channelNumber = [fread(fid,1,'uint32'); channelNumber];
  beginningBar = [fread(fid,1,'uint32'); beginningBar];
  endBar = [fread(fid,1,'uint32'); endBar];
  vertExpFactor = [fread(fid,1,'uint32'); vertExpFactor]; 
  voltageOffset =[fread(fid,1,'uint32'); voltageOffset];
  isGridEnabled = [fread(fid,1,'uint32'); isGridEnabled];
  isEngineeringUnitEnabled = [fread(fid,1,'uint32'); isEngineeringUnitEnabled];
  colorOfDisplay = [fread(fid,1,'uint32'); colorOfDisplay];
  multiChannelIndex = [fread(fid,1,'uint32'); multiChannelIndex];
  numChannelsForMultiChannelDisp = [fread(fid,1,'uint32'); numChannelsForMultiChannelDisp];
  multiChannelDispStyle = [fread(fid,1,'uint32'); multiChannelDispStyle];
end    
fread(fid,1,'uint32'); % value only used internally
fread(fid,16,'char'); % unused parameter for future use
yearOfDataCollection = fread(fid,1,'uint16'); 

2 个答案:

答案 0 :(得分:1)

我首先建议,只需将所有数据作为字节数组一次读入。您将能够更快地调试问题:

fid = fopen('MIC1.001','rb');
data = fread(fid);
fclose(fid);
% could look at it as all chars, just for debugging
char(A)'

数据作为大量字节读入。然后,您将通过适当地转换它们来解析字节。您可能想尝试首先测试您的方法:

% create a binary file to follow the same format as the specified file
fid = fopen('test.dat','wb');
% Put in 8 character string for file ID
aa = 'myfile0';
fwrite(fid,aa);
% Null terminate it, (I guess)
fwrite(fid,0);
% write the 2 byte file major revision
aa = 1000;
fwrite(fid,aa,'uint16');
% write the 2 byte file minor revision
aa = 5000;
fwrite(fid,aa,'uint16');
% write the 4 byte number of modules
aa = 65536;
fwrite(fid,aa,'uint32');
fclose(fid);

% read the entire file in
fid = fopen('test.dat','rb');
A = fread(fid);
fclose(fid);

% Try to read the file id
disp(char(A(1:8))')
% Try to read the file major revision
majorByte1 = dec2hex(A(9));
majorByte2 = dec2hex(A(10));
% see if it needs byte swapped
tmp1 = hex2dec([majorByte1 majorByte2]);
tmp2 = hex2dec([majorByte2 majorByte1]);
fprintf(1,'File Major: %d ? = %d\nFile Major: %d ? = %d\n',1000,tmp1,1000,tmp2);

对于输出我得到:

myfile0 
File Major: 1000 ? = 3715
File Major: 1000 ? = 1000

所以,对我来说,我需要字节交换数据,也许你也这样做? : - )

修改

使用来自Matlab文档的fread执行此操作:

  

A = fread(fileID,sizeA,precision,skip,machineformat)读取数据   使用指定的machineformat。

对于你的情况:

A = fread(fid,2,'uint16',0,'b');

我假设您使用的是小端机器,将其交换为小端,只需使用l代替b

答案 1 :(得分:0)

应给出dec2hex转换的位数(0x0A0C!= 0xAC):

majorByte1 = dec2hex(A(9), 2);
majorByte2 = dec2hex(A(10), 2);
% see if it needs byte swapped
tmp1 = hex2dec([majorByte1 majorByte2]);
tmp2 = hex2dec([majorByte2 majorByte1]);