MATLAB fread函数分析

来源:互联网 发布:怎么查淘宝宝贝降权 编辑:程序博客网 时间:2024/05/21 11:28
   今天起开始总结下MATLAB的文件操作函数。MATLAB的确用起来很方便,前提是你了解它的函数~

      MATLAB的帮助文档看的那叫一个似懂非懂啊,特此总结。对我而言, fread的主要调用形式是这样的:

     

[html] view plaincopyprint?
  1. data = fread(fid, N, 'str')  

       fid不用说,自然是文件句柄(如fid=fopen('abc.txt' ,'r')),N是读入的元素个数,'str'是格式。在以前不会用的时候,格式都是直接省略的,这个时候函数就一个字节一个字节地从文件中读入数据,再在MATLAB中转化为double形式。

      如果文件时二进制文件,这样读当然没问题,如果想要读入的是文本,那就不行了。文本也是一个字节一个字节地读,但是最后应该转化为char型:

[cpp] view plaincopyprint?
  1. >> frewind(f);  
  2. >> a=fread(f,1,'char=>char')  
  3. a =  
  4. B  
  5. >> frewind(f);  
  6. >> a=fread(f,1,'uchar=>uchar')  
  7. a =  
  8.    66  
[cpp] view plaincopyprint?
  1. <P>>> class(a)</P><P>ans =</P><P>uint8</P>>> frewind(f);  
  2. >> a=fread(f,1,'uint8=>char')  
  3. a =  
  4. B  
  5. >> frewind(f);  
  6. >> a=fread(f,1,'uchar=>char')  
  7. a =  
  8. B  
[cpp] view plaincopyprint?
  1. >> frewind(f);  
  2. >> a=fread(f,1,'int8=>char')  
  3. a =  
  4. B  


       上面是一个BMP文件的例子,读入的是文件第第一个字节,BMP文件以“BM”开头,第一个自己自然是B。int8、uint8、char、uchar是几种一个字节的数据类型。在例子中,a=>b表示以a的类型读入,再转化为b类型。a的作用是控制每次读入的字节数,然后转化为相应的类型,形成一定的数值,b的作用是在a的基础上进行转化。这里都是一个字节,读入以后,最后如果是char型,就都变成了字母B,如果是uchar型,就变成uint8。

    以上是字节数相同的例子,a=>b,a似乎没多大用,但是,当字节数不同时,就大有用场了:

[html] view plaincopyprint?
  1. >> frewind(f);  
  2. >> a=fread(f,1,'uint16=>uint8')  
  3. a =  
  4.   
  5.   255  
  6. % 在这里,uint16是两个字节的,所以一次性读入2个字节,先以uint16的形式读入,整数的排列规则是很简单的,假设低字节为a,高字节为b,那就等于b*256+a,得到的数肯定超过256,最后又要转化为uint8,因此只能截断了,uint8一个字节,最大能表示的数就是255,因此返回255.  
[html] view plaincopyprint?
  1.    
[html] view plaincopyprint?
  1. >> frewind(f);  
  2. >> a=fread(f,1,'uint16=>float')  
  3.   
  4. a =  
  5.   
  6.        19778  
[html] view plaincopyprint?
  1. % 这里,说明以uint16读入的数,得到为19778,然后再转为单精度的float型,还是19778,当然,类型已经换掉了  
  2.   
  3. >> frewind(f);  
  4. >> a=fread(f,1,'*uint32')  
  5.   
  6. a =  
  7.   
  8.     37637442  
[html] view plaincopyprint?
  1. % *uint32相当于uint32=>uint32,以4个字节的形式读入,成为一个整数。  
[html] view plaincopyprint?
  1. >> frewind(f);  
  2. >> a=fread(f,1,'uint32=>float')  
  3.   
  4. a =  
  5.   
  6.     37637440  
  7. % 以四个字节的形式读入,先变成整型,再变成float型,末尾的2丢掉了,是精度问题?  
[html] view plaincopyprint?
  1. >> class(a)  
  2. ans =  
  3. single  
[html] view plaincopyprint?
  1.    
[html] view plaincopyprint?
  1. >> frewind(f);  
  2. >> a=fread(f,1,'uint32=>double')  
  3. a =  
  4.     37637442  
  5. % 转化为double,精度就够了  
[html] view plaincopyprint?
  1. >> frewind(f);  
  2. >> a=fread(f,1,'float=>double')  
  3. a =  
  4.  1.3981e-037  
[html] view plaincopyprint?
  1. % 最精彩的来了,尽管float和uint32都是4个字节,但是这里得到的数却不与上面相等。前面说了,a=>b,系统以a的格式,读入相应的字节数,转化为a类型的一个数值,再将a转为b类型,这里读入的时候,以float的规则来读,再将float转为double,无非是提高精度而已。  
  2. >> frewind(f);  
  3. >> a=fread(f,1,'float=>uint32')  
  4. a =  
  5.            0  
[html] view plaincopyprint?
  1. % 读到的是1.3981e-037,转化为整数,当然是0了  

 

      此外,我还尝试过以下格式:

[html] view plaincopyprint?
  1. >> a=fread(f,1,'3*int8=>char')  
  2.   
  3. a =  
  4.   
  5. B  

N*a=>b的形式,一般用在有skip(跳过)的地方,这里没有在后面的参数中指定跳过,所以默认的跳过为零,得到的结果还是字母B。跳过形式往往用在按bit读的时候,

[html] view plaincopyprint?
  1. >> a=fread(f,3,'*uint8')  
  2.   
  3. a =  
  4.   
  5.    66  
  6.    77  
  7.    62  
  8.   
  9. >> frewind(f);  
  10. >> a=fread(f,4,'1*int8=>int8',1)  
  11.   
  12. a =  
  13.   
  14.    66  
  15.    62  
[html] view plaincopyprint?
  1. 2  
[html] view plaincopyprint?
  1. 0  
  2. 意,前面读入的时候按int8读,所以跳过的时候,跳的是1个int8的长度,因此跳过了77,结果为66,,62  
[html] view plaincopyprint?
  1. >> frewind(f);  
  2. >> a=fread(f,2,'1*bit8=>int8',8)  
  3.   
  4. a =  
  5.   
  6.    66  
  7.    62  
[html] view plaincopyprint?
  1. % 前面是bit8,凡是bitN的类型的,后面跳过时都指的是跳过几个bit  
[html] view plaincopyprint?
  1. <P>>> frewind(f);  
  2. >> a=fread(f,2,'1*bit16=>int8',8)</P><P>a =</P><P>  127  
  3.     2</P><P>%前面读入是按两个字节读(bit16),因此第一次读进来的是66和77,后来要转为int型,int表示的范围-128~127,因此就变成127了。然后跳过了62,下一个数字是2,在下一个数字是0,因此加在一起就是0了。</P><P> </P>  


另外,最全的调用形式是

[data, n] = fread(fid, N, 'a=>b', nn, 'l/n/b/...')

最后一个参数的作用是指定大端小端,windows这种用intel的是小端,低地址放低字节,所以读进66和77,66在低地址,他是低字节,77是高地址,是高字节,结果为66+77*256,UINX之类的一般是大端。网络通信一般是大端

'b'   :大端

'l'    :小端

'n'   :原来是大端现在就是大端,原来小端现在就是小端!

返回的n是指实际读进了几个单元。把n和N一比较,相等就说明确实读进了所需要的N个数据。

 

测试用的文件:



原创粉丝点击