MATLAB读取二进制文件(十六进制)的内容,知道格式

时间:2017-06-01 13:22:39

标签: matlab hex

在使用Win10 x64的笔记本电脑上,我使用了一种软件,可以将直方图数据保存到文件中,并使用' .dat'扩展,我试图在Win7 x64上打开它。

在软件文档中,该文件具有以下格式:

  1. 字节0到7是描述数字的64位浮点(图的上限)
  2. 字节8到15是描述数字的64位浮点(图的下界)
  3. 字节16到19是无符号32位整数,设置为0或1
  4. 字节20到23是设置为0或1
  5. 的无符号32位整数
  6. 字节24到27是一个无符号的32位整数,设置为图的宽度,以像素为单位
  7. 字节28到31是设置为图表高度的无符号32位整数,以像素为单位
  8. 在给定宽度和高度的情况下,
  9. 字节32到800031对于图中的每个点都有一个无符号的32位整数。 (所以它的4 *宽*高度= 800 000)
  10. 现在,如果我用十六进制编辑器打开文件,我可以看到这些值对应于上面的编号点:

    1. '11 EA 2D 81 99 97 71 3D'
    2. '49 AF BC 9A F2 D7 7A 3E'
    3. '01 00 00 00'
    4. '00 00 00 00'
    5. 'F4 01 00 00'
    6. '90 01 00 00'
    7. 文件的其余部分
    8. 从我所看到的,查看3的值,并知道应该是1或0我可以看到它应该实际读取'00 00 00 01'。在线阅读一些信息,我认为这是“小端”#。

      在我的Win7笔记本电脑上[cinfo, maxsize, ordering] = computer在Matlab中编写以下内容,我得到答案'L'。 Matlab中的字符编码是' windows-1252'。

      使用各种工具在线测试结果值我得到以下结果:

      • http://babbage.cs.qc.cuny.edu/IEEE-754.old/64bit.html用于1。 并将字节输入为十六进制,little-endian(所以,值 3D719799812DEA11代替11EA2D819997713D)我得到了结果 1.000e-12
      • 使用相同的网址2.(所以,3D719799812DEA11的值代替 11EA2D819997713D),我得到1.0001e-7的结果。
      • 使用相同的url获取little-endianed的值,然后输入 它进入一个将unsigned int转换为二进制的站点,另一个转换为二进制 将二进制转换为小数,对于3,4,5和6,我得到了 值分别为1,0,500和400。

      这意味着上述编号点的值为:

      1. 1E-12
      2. 1E-7
      3. 1
      4. 0
      5. 500(宽度,以像素为单位)
      6. 400(高度,以像素为单位)
      7. 4 * 500 * 400 = 800 000,所以看起来是正确的。
      8. 所以,如果我尝试在Matlab中打开文件,我知道我应该找到什么。 这就是我到目前为止所做的:

        name = 'histogram.dat';
        fid = fopen(name,'r');
        v = fread(fid);
        

        这为v提供了800032x1倍。如果我打开v向量,我会看到以下内容:

        • 第1至7栏(第1栏):[17; 234; 45; 129; 153; 151; 113]
        • 第8至15栏(第2栏):[61; 73; 175; 188; 154; 242; 215; 122]
        • 第16至19栏(第3栏):[62; 1; 0; 0]
        • 第20至23栏(第4列):[0; 0; 0; 0]
        • 第24至27栏(第5栏):[0; 244; 1; 0]
        • 第28至31栏(第6栏):[0; 144; 1; 0]
        • 第32栏至第8000032号(第7栏):其余部分

        接下来,我删除了所有内容,然后尝试按以下方式读取二进制文件:

        name = 'histogram.dat';
        fid = fopen(name,'r');
        c1 = fread(fid,8,'float64');
        c2 = fread(fid,8,'float64');
        c3 = fread(fid,4,'uint32');
        c4 = fread(fid,4,'uint32');
        c5 = fread(fid,4,'uint32');
        c6 = fread(fid,4,'uint32');
        

        现在我得到了完全不同的东西。

         c1 = [1.00e-12; 1.00e-07; 4.90e-324; 8.48e-312; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314 ];
         c2 = [-1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314];
         c3 to c6 = [2.1475e09; 2.1475e09; 2.1475e09; 2.1475e09];
        

        因此,似乎没有按预期工作。如何在Matlab中打开文件,并且具有与我预期相同的值?而且,如何从31到最后打开字节?我想我一直读到每个4字节,然后得到值?

        另外,如果我得到每个向量的HEX值,我做hex2num(对于前2个,float64s)或hex2dec(对于下一个向量,uint32s),我得到了正确的结果。我还应该先hex2numhex2dec二进制数字吗?

        另一种可能性是在普通的十六进制编辑器中打开文件,获取在Matlab中导入的大矢量,将字节顺序与swapbyes交换,然后执行hex2num/dec。然后我会得到正确的值。

2 个答案:

答案 0 :(得分:1)

fread的第二个参数是要读取的元素数,而不是字节数。它将根据您指定的数据类型调整字节数。例如,要将单个float64读入c1,您实际需要

c1 = fread(fid,1,'float64');

您需要相应地调整其他值。要将其余数据读入文件末尾,请将第二个参数替换为Inf

无需转换为十六进制值或从十六进制值转换;十六进制值只是关于值如何在屏幕上显示。

答案 1 :(得分:0)

此外,您可以使用

读取字节向量中的整个数据
bytevec = fread(fid,inf,'uint8');

然后,您可以通过索引手动排列bytevec的元素(或使用reshape)并调用

value = cast(bytevec(i1:i2), type);

然后将其转换为默认的matlab double类型而不更改数据:

double_value = typecast(value,'double');
相关问题