在科學計算中,經常有大量的數據要保存,這些計算程序很多是用Fortran寫的,保存數據時為了占用更小的體積,更快的讀寫速度,避免浮點數精度損失,通常用二進制文件讀寫數據。而對數據進行分析時,又常常使用python,matlab等語言進行數據分析和可視化。這時候就要用matlab來讀取fortran保存的二進制文件。
可以把數據寫成matlab可以讀取的形式,調用matlab讀取數據的API.或者寫成HDF5格式.或者直接用Fortran二進制寫文件,用下面的方法讀入matlab中.
Binary files that are generated by FORTRAN are quite different than ones that are expected by MATLAB. MATLAB expects a flat binary file. FORTRAN binary files are not flat.An unformatted FORTRAN binary file contains record length information along with each record. A record is a WRITE statement.The record length information is tagged on at the beginning and end of each record.
下面這段fortran代碼有三個write語句,即文件中有三個記錄(record),但是每個記錄首尾會插入表示record長度信息的二進制數據。用matlab讀取的時候要把這些長度信息去掉。
program wrt_bin
character*72 name
real*4 xsource, zsource, dt
integer*4 ntrace, nt
name='I am a genius groundhog! Run! Run! Run!'
xsource=1.1
zsource=2.2
dt=3.3
ntrace=4
nt=5
open(unit=11, file='wrt_bin.bin', form='unformatted',
+ status='new')
WRITE(11) NAME
WRITE(11) XSOURCE,ZSOURCE,DT
WRITE(11) NTRACE,NT
close(11)
end
You will have to modify your MATLAb file to read out the record length information and access the data in which you are interested. An alternative would be to use the FSEEK() command in MATLAB to jump over the record length information and access the data directly.
Here is an example file that does so:
fid=fopen('wrt_bin.bin', 'rb');
fseek(fid, 4, 'cof');
name=setstr(fread(fid, 72, 'uchar'))';
fseek(fid, 4, 'cof');
fseek(fid, 4, 'cof');
xsource=fread(fid, 1, 'float32');
zsource=fread(fid, 1, 'float32');
dt=fread(fid, 1, 'float32');
fseek(fid, 4, 'cof');
fseek(fid, 4, 'cof');
ntrace=fread(fid, 1, 'int32');
nt=fread(fid, 1, 'int32');
fclose(fid);
xsource, zsource, dt, ntrace, nt
fortran Stream Input/Output
事實上可以用流輸出(stream output)去掉record length 信息
A binary file write adds extra record delimiters (hidden from programmer) to the beginning and end of recors. In fortran 2003, using access method 'stream' avoids this and implements a C-programming like approach:
REAL header(20), data(300)
OPEN(10,file="mydata.dat",access='stream')
WRITE(10) header
WRITE(10) data
CLOSE(10)