英特尔 Fortran 形式的标准等效形式 = 'binary'

Bal*_*azs 2 file-io fortran binaryfiles gfortran intel-fortran

我对为使用英特尔 Fortran 编译器进行编译而编写的 Fortran 代码有疑问。

我遇到的具体问题是声明OPEN。我尝试重写源代码,以便可以使用免费编译器(即 GNU Fortran)编译它,并且我成功了,但我遇到了一些问题。

有一些带有 的临时文件输出OPEN(access = 'direct', form = 'binary', status = 'replace'...),但form = 'binary'不是标准的,GNU Fortran 编译器不支持。

在网上寻找解决方案后,我发现form = 'unformatted'应该是等效的并且 GNU Fortran 可以处理它。是的,确实如此,我能够编译并且代码运行正确。然而,该代码是科学计算,在以这种方式打开的这些文件中生成大量数据。我的问题是,form = 'unformatted'结果文件比form = 'binary'.

这样,在某些情况下,我没有足够的硬盘空间来成功运行未格式化的格式,而使用二进制文件则可以。是否有英特尔 Fortran 的“二进制文件”的等效项可以与 GNU Fortran 一起使用并产生类似的文件大小?

根据要求,我添加了一个简短的、简化的示例代码:

subroutine init
use module params  ! contains param1, param2, param3, ... which are inetger or real
common /params2/ maxi, maxj, maxk, limit, recnum ! integers defined elsewhere
real*8, allocatable :: x(:)
... other variables
open (unit = 5, file = 'data.txt', access = 'direct',
 *    form = 'binary', recl = 16*maxk+8, status = 'replace')
write(5, rec = 1) param1, param2, param3, maxi, maxj, maxk, limit, recnum ...
recnum = 2
do i = 1, maxi
  do j = 2, maxj
     ... do some stuff with x
     write(55, rec=recnum) x(0), (xt(k), xt(limit-k), k = 1, maxk)
  recnum = recnum + 1
  done
done
close(5)
end subroutine init

program xx
common /params2/ maxi, maxj, maxk, limit, recnum
...
call subroutine init
...
open (unit = 5, file = 'data.txt', access = 'direct',
 *   form = 'binary', recl = 16*maxk+8, status = 'old')
... do some stuff
read(5, rec=1) param1, param2, param3, maxi, maxj, maxk, limit, recnum, ...
... do some stuff
recnum = 1
do i = 1, maxi
  do j = 2, maxj
  recnum = recnum + 1
     ... do some stuff
     read(5, rec=recnum) x(0), (xt(k), xt(limit-k), k = 1, maxk)
     ... do some stuff
  done
done
close(5)
end program
Run Code Online (Sandbox Code Playgroud)

读取第一条记录是必要的,因为 my 生成的 program xx文件来自先前的运行(调用可能不会在每次运行时发生),并且需要读取一些参数来解释 中的数据。data.txtsubroutine initsubroutine initdata.txt

这样会生成多个文件,并且并不总是需要第一个记录。我认为access = stream如果读取第一条记录,即使没有必要,也可能会起作用。

但是,当我替换access = directaccess = stream并删除recl以及每次出现rec =inWRITE()或 时READ(),我都会在文件 I/O 期间收到不一致的运行时错误。

Vla*_*r F 5

我无法找到完全相同的副本,但以前曾在这里接受过治疗。

  form='binary'
Run Code Online (Sandbox Code Playgroud)

是完全不标准的。标准方法是使用

  access='stream', `form='unformatted'
Run Code Online (Sandbox Code Playgroud)

这将启用 Fortran 2003 的标准流访问,Fortran 2003 是在 C 基础上建模的,并且可以在所有相当新的编译器中使用。

基本上,它form='binary'与该语言的其余部分不太兼容。正确的方法是真正改变access,这就是你可能感到困惑的原因。

顺序访问和直接访问都是基于记录的,可能会导致除了数据之外还写入记录标记。非标准form='binary'改变了这一点,但正确的方法是使用可以格式化和未格式化的流访问。特别是未格式化非常方便,让您可以准确保存内存中的字节,而无需任何其他标记。