MATLAB读取二进制文件的结尾 您所在的位置:网站首页 MATLAB转换为二进制 MATLAB读取二进制文件的结尾

MATLAB读取二进制文件的结尾

2023-04-30 01:14| 来源: 网络整理| 查看: 265

我想这是你之前问题MATLAB reading a mixed data type binary file的一个变体。

您的目标是读取包含混合数据类型的二进制文件。在您的示例中,它包含2列:

1x single值(4字节)和1x int16值(2字节)。

有几种方法可以读取这种类型的文件。它们在速度上有所不同,因为一些方法最小化了磁盘访问,但需要更多的临时内存,而另一些方法只使用了所需的内存,但需要更多的磁盘访问(=较慢)。

最终,我要向你展示的3种方法产生的结果完全一样,。

这个问题的直接答案是下面的版本#3,但我鼓励你看看这里描述的另外两个选项,它们都非常值得理解。

出于示例的目的,我必须按照您所描述的那样创建一个二进制文件。这是通过以下方式完成的:

%% // write example file A = single(linspace(-3,1,11)) ; %// a few "float" (=single) data B = int16(-5:5) ; %// a few "int16" data fileID = fopen('testmixeddata.bin','w'); for il=1:11 fwrite(fileID,A(il),'single'); fwrite(fileID,B(il),'int16'); end fclose(fileID);

这将创建一个两列二进制文件,其中的列为:

11 float类型的值从-3到1。11 int16类型的值从-5到+5。

供将来参考:

>> disp(A) -3.0000 -2.6000 -2.2000 -1.8000 -1.4000 -1.0000 -0.6000 -0.2000 0.2000 0.6000 1.0000 >> disp(B) -5 -4 -3 -2 -1 0 1 2 3 4 5

在下面的每个解决方案中,第一列将被读入名为varSingle的变量中,第二列将被读入名为varInt16的变量中。

1)一次读取所有数据-转换为正确的类型

%% // SOLUTION 1 (fastest) : 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); colSize = [4 2] ; %// number of byte for each column [4 byte single, 2 byte int16] R = reshape( R , sum(colSize) , [] ) ; %// reshape data into a matrix (6 is because 4+2byte=6 byte per column) temp = R(1:4,:) ; %// extract data for first column into temporary variable (OPTIONAL) varSingle = typecast( temp(:) , 'single' ) ; %// convert into "single/float" temp = R(5:end,:) ; %// extract data for second column varInt16 = typecast( temp(:) , 'int16' ) ; %// convert into "int16"

这是我最喜欢的方法。特别是在速度方面,因为它最小化了磁盘上的读取/寻道操作,并且大多数post计算都是在内存中完成的(比磁盘操作快得多)。

请注意,我使用的临时变量只是为了清晰/详细,如果您正确地对原始数据进行索引,则可以完全避免使用临时变量。

要理解的关键是typecast函数的使用。好消息是it got even faster since 2014b。

2)逐列读取(使用"skipvalue")传递方法

%% // SOLUTION 2 : Read column by column (using "skipvalue") - 2 pass approach col1size = 4 ; %// size of data in column 1 (in [byte]) col2size = 2 ; %// size of data in column 2 (in [byte]) fileID = fopen('testmixeddata.bin'); varSingle = fread(fileID,'*single',col2size) ; %// read all "float" values, skipping all "int16" fseek(fileID,col1size,'bof') ; %// rewind to beginning of column 2 at the top of the file varInt16 = fread(fileID,'*int16',col1size) ; %// read all "int16" values, skipping all "float" fclose(fileID);

这也行得通。它工作得很好。但它将比上面的方法1慢,因为您必须扫描文件两次。如果文件非常大,并且上述方法1由于out of memory错误而失败,则这可能是一个很好的选择。

3)逐元素读取

%% // SOLUTION 3 : Read element by element (slow - not recommended) fileID = fopen('testmixeddata.bin'); varSingle=[];varInt16=[]; while ~feof(fileID) try varSingle(end+1) = fread(fileID, 1, '*single' ) ; varInt16(end+1) = fread(fileID, 1, '*int16' ) ; catch disp('reached End Of File') end end fclose(fileID);

这也是可行的,如果你正在编写C代码,那就更好了。但在Matlab中,这不是推荐的方法(最终由您选择)

如前所述,上面的3个方法将提供我们在开始时在文件中编写的内容:

>> disp(varSingle) -3.0000 -2.6000 -2.2000 -1.8000 -1.4000 -1.0000 -0.6000 -0.2000 0.2000 0.6000 1.0000 >> disp(varInt16) -5 -4 -3 -2 -1 0 1 2 3 4 5


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有