LZN's Blog CodePlayer

【已解决】NCL写binary文件Fortran读出错——BigEndian问题

2014-10-19
LZN

ncl写二进制文件非常方便,setfileoption+fbinrecwrite语句即可。处理模式输出的加热数据测试了一下,非常迅速搞定。随后需要用到fortran代码来读写二进制文件,没想到却遇到大问题。

ncl下采用fbinrecwrite写入的文件为fortran下的sequential读取方式(貌似这个才是符合ieee标准的),按照官网指示,代码很容易编译通过,但是执行出错。ifort编译执行错误结果:

forrtl: severe (98): cannot allocate memory for the file buffer - out of memory, unit 100, file /users/yangsong3/L_Zealot/F/f90/CAM4_PTENDT_DIFF_mon.dat

采用gfortran编译,同样执行出错:

At line 12 of file read_heat_diff.f90 (unit = 100, file = '../data/model_post/CAM4_PTENDT_DIFF_mon.dat') Fortran runtime error: End of file

第一次在linux平台下编译自己写的fortran代码,多少还是有些心虚。ifort表示内存不足,gfortran表示读到文件末尾,有些莫名其妙,检查路径文件名,文件大小,读取方式,貌似都没问题,折腾许久没有结果。

问题只能回溯到ncl那么简单的二进制写入上,fbinrecwrite看上去没什么问题,setfileoption中的几个选项值得怀疑,查了下BigEndian的问题,是这样描述的:

其实big endian是指低地址存放最高有效字节(MSB),而little endian则是低地址存放最低有效字节(LSB)。 用文字说明可能比较抽象,下面用图像加以说明。比如数字0x12345678在两种不同字节序CPU中的存储顺序如下所示: Big Endian 低地址                                   高地址 -----------------------------------------> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |   12  |   34  |   56  |   78   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Little Endian 低地址                                   高地址 -----------------------------------------> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |   78|   56  |   34  |   12   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

虽然看上去出错信息并不是这么指向的,但还是要试一试,查了下fortran在字节序处理的问题,果然,一行open语句赫然入眼:

open(…,convert=”big_endian”)

加入测试,我擦嘞……居然可以了,果然是字节序的问题。原来fortran默认的是非人的little endian,好吧……关键是运行出错给出的那些错误信息,完全无厘头,真是对编译器失望了。另外SGI编译器默认为BigEndian。

另外fortran读ncl写出的多维二进制数据的时候,注意维数方向是相反的哦!如ncl数组(33,44),fortran(44,33)

【参考资料】

http://blog.csdn.net/sunshine1314/article/details/2309655 BigEndian和LittleEndian

http://bbs.lasg.ac.cn/?action-viewthread-tid-13303

http://www.360doc.com/content/11/0216/10/2609140_93438395.shtml

 


Comments

Content