使用access=stream写入大型Fortran二进制文件的格式疑问
Fortran Stream Access 二进制文件的写入与读取问题
嗨,我看你在理解Fortran二进制文件格式时碰到了麻烦,尤其是对access='stream'选项的作用有疑问。先结合你写的代码来分析下:
首先你这段写入子程序:
SUBROUTINE write_field(d,m,outfile) IMPLICIT NONE REAL, INTENT(IN) :: d(m,m,m) INTEGER, INTENT(IN) :: m CHARACTER(len=256), INTENT(IN) :: outfile OPEN(7,file=outfile,form='unformatted',access='stream') WRITE(7) d CLOSE(7) END SUBROUTINE write_field
你的想法其实是对的:access='stream'确实会抑制Fortran默认无格式文件的记录边界标记(就是那些额外的整数头/尾),这段代码写入的就是数组d在内存里的原始二进制数据,没有任何额外的包装字节,完全按顺序写入磁盘。
那你碰到的问题大概率出在读取环节,或者是对数据匹配的细节没注意到,给你几个关键的注意点和正确读取的示例:
正确读取的对应代码
要读取这个文件,必须用同样的stream模式打开,并且保证数据类型、数组维度完全匹配:
SUBROUTINE read_field(d,m,infile) IMPLICIT NONE REAL, INTENT(OUT) :: d(m,m,m) INTEGER, INTENT(IN) :: m CHARACTER(len=256), INTENT(IN) :: infile OPEN(8,file=infile,form='unformatted',access='stream') READ(8) d CLOSE(8) END SUBROUTINE read_field
必须注意的几个细节
- 数据精度严格匹配:你写入时用的是默认
REAL(通常是单精度),读取时不能换成DOUBLE PRECISION或者REAL*8,否则会因为字节数不匹配读乱数据。如果要写双精度,写入和读取都要统一用DOUBLE PRECISION类型。 - 数组维度完全一致:写入的是
m×m×m的三维数组,读取时的m必须和写入时的数值完全相同,不然会出现数据错位或者内存越界的问题。 - 不要混用访问模式:如果用普通的顺序访问(
access='sequential',默认模式)去读stream模式写的文件,程序会把原始数据当成带记录标记的内容来解析,自然会出错。
补充说明
如果之前你习惯了用默认顺序访问的无格式文件,那每个WRITE语句都会在数据前后加上记录长度的标记(4字节或8字节,取决于编译器和系统),而stream模式彻底移除了这些额外信息,让文件变成纯粹的二进制数据流,和C语言写的二进制文件格式一致,方便跨语言读取。
内容的提问来源于stack exchange,提问作者Mead
相关产品推荐
相关产品推荐

