我希望第1列位于' int8'格式和第2列是' float'
这是我到目前为止的尝试:
FileID= fopen ('MyBinaryFile.example');
[A,count] = fread(FileID,[nrows, 2],['int8','float'])
这不起作用,因为我收到错误消息'错误使用fread' '无效精度'
一旦我成功完成了这一点,我将继续绘制。
对于有matlab经验的人来说,这可能是一个非常简单的解决方案,但我还没有成功地在互联网上找到解决方案。
提前感谢任何可以提供帮助的人。
答案 0 :(得分:3)
你应该知道Matlab 不能在矩阵中保存不同的数据类型(它可以在cell array
中这样做,但这是另一个主题)。因此,尝试在一个矩阵中一次性读取混合类型文件是没有意义的......这是不可能的。
除非您需要cell array
,否则您必须为2列不同类型使用2个不同的变量。一旦建立,有很多方法可以读取这样的文件。
出于示例的目的,我必须按照您的描述创建二进制文件。这样做是这样的:
%% // write example file
A = int8(-5:5) ; %// a few "int8" data
B = single(linspace(-3,1,11)) ; %// a few "float" (=single) data
fileID = fopen('testmixeddata.bin','w');
for il=1:11
fwrite(fileID,A(il),'int8');
fwrite(fileID,B(il),'single');
end
fclose(fileID);
这创建了一个2列二进制文件,第一列:类型为int8
的11个值从-5到+5,第二列:类型为float
的11个值从-3到1。
在下面的每个解决方案中,第一列将在名为C
的变量中读取,第二列将在名为D
的变量中读取。
%% // Read all data in one go - convert to proper type after
fileID = fopen('testmixeddata.bin');
R = fread(fileID,'uint8=>uint8') ; %// read all values, most basic data type (unsigned 8 bit integer)
fclose(fileID);
R = reshape( R , 5 , [] ) ; %// reshape data into a matrix (5 is because 1+4byte=5 byte per column)
temp = R(1,:) ; %// extract data for first column into temporary variable (OPTIONAL)
C = typecast( temp , 'int8' ) ; %// convert into "int8"
temp = R(2:end,:) ; %// extract data for second column
D = typecast( temp(:) , 'single' ) ; %// convert into "single/float"
这是我最喜欢的方法。特别是速度,因为它最大限度地减少了磁盘上的读/写操作,大多数后期计算都在内存中完成(比磁盘操作快得多)。
请注意,我使用的临时变量仅用于清晰/详细,如果您正确索引原始数据,则可以完全避免它。
要理解的关键是使用typecast
功能。好消息是it got even faster since 2014b。
%% // Read column by column (using "skipvalue") - 2 pass approach
col1size = 1 ; %// size of data in column 1 (in [byte])
col2size = 4 ; %// size of data in column 2 (in [byte])
fileID = fopen('testmixeddata.bin');
C = fread(fileID,'int8=>int8',col2size) ; %// read all "int8" values, skipping all "float"
fseek(fileID,col1size,'bof') ; %// rewind to beginning of column 2 at the top of the file
D = fread(fileID,'single=>single',col1size) ; %// read all "float" values, skipping all "int8"
fclose(fileID);
也有效。它工作得很好......但可能比上面慢得多。虽然为其他人阅读可能更清晰的代码......我觉得这很难看(但我已经用这种方式好几年了,直到我使用上面的方法)。 / p>
%% // Read element by element (slow - not recommended)
fileID = fopen('testmixeddata.bin');
C=[];D=[];
while ~feof(fileID)
try
C(end+1) = fread(fileID,1,'int8=>int8') ;
D(end+1) = fread(fileID,1,'single=>single') ;
catch
disp('reached End Of File')
end
end
fclose(fileID);
谈论丑陋的代码......它确实有用,如果你正在编写C
代码,那就不错了。但是在Matlab中......请避免! (嗯,你的选择最终)
如果真的想要在一个变量中使用所有这些变量,它可以是结构或单元格数组。对于单元格数组(保持矩阵索引样式),只需使用:
%% // Merge into one "cell array"
Data = { C , D } ;
Data =
[11x1 int8] [11x1 single]