“意外”;填充“;在Fortran未格式化文件中

“意外”;填充“;在Fortran未格式化文件中,fortran,binaryfiles,binary-data,Fortran,Binaryfiles,Binary Data,我不懂Fortran中未格式化文件的格式 例如: open (3,file=filename,form="unformatted",access="sequential") write(3) matrix(i,:) 将矩阵的一列输出到文件中。我发现它在文件的两端都有4个字节,但是我真的不明白为什么,或者如何控制这种行为。有没有办法删除填充?对于未匹配的IO,Fortran编译器通常在记录的开头和结尾写入记录的长度。大多数但并非所有编译器都使用四个字节。这有助于读取记录,例如,末尾的长度有助于退

我不懂Fortran中未格式化文件的格式

例如:

open (3,file=filename,form="unformatted",access="sequential")
write(3) matrix(i,:)

将矩阵的一列输出到文件中。我发现它在文件的两端都有4个字节,但是我真的不明白为什么,或者如何控制这种行为。有没有办法删除填充?

对于未匹配的IO,Fortran编译器通常在记录的开头和结尾写入记录的长度。大多数但并非所有编译器都使用四个字节。这有助于读取记录,例如,末尾的长度有助于退格操作。您可以使用新的Fortran 2003流IO模式来抑制这种情况,该模式是为了与其他语言兼容而添加的。在open语句中使用access='stream'。

Fortran IO是基于记录的,而不是基于流的。每次通过
write()
写入内容时,不仅要写入数据,还要写入该记录的开始和结束标记。两个记录标记都是该记录的大小。这就是为什么在一次写入中写入一组实数(一条记录:一个开始标记、一组实数、一个结束标记)与在单独写入中写入每个实数(多条记录、一个开始标记、一个实数和一个结束标记)的大小不同的原因。如果您正在写大型矩阵,这一点非常重要,因为如果写得不正确,您可能会夸大职业

正是出于这个原因,我从来没有对未格式化的输出使用顺序访问。但是,这取决于应用程序,有时使用记录长度指示器(特别是对于非结构化数据)很方便。正如steabert在中所建议的,您可以通过使用关键字参数
ACCESS='DIRECT'
来避免这种情况,在这种情况下,您需要指定记录长度。这种方法便于高效地存储大型多维结构化数据(固定记录长度)。以下示例写入大小等于数组大小的未格式化文件:

REAL(KIND=4),DIMENSION(10) :: a = 3.141
INTEGER                    :: reclen

INQUIRE(iolength=reclen)a
OPEN(UNIT=10,FILE='direct.out',FORM='UNFORMATTED',&
     ACCESS='DIRECT',RECL=reclen)
WRITE(UNIT=10,REC=1)a
CLOSE(UNIT=10)

END

请注意,从可移植性的角度来看,这不是理想的方法。在使用直接访问写入的未格式化文件中,没有关于每个元素大小的信息。描述数据大小的自述文本文件对我来说很好,我更喜欢这种方法,而不是顺序模式下的填充。

Fortran无格式IO我非常熟悉使用Intel和Gnu编译器的不同输出。幸运的是,我在20世纪70年代IBM公司的丰富经验使我能够解码东西。Gnu使用4字节整数计数器填充记录,给出记录长度。英特尔使用一个1字节计数器和一些嵌入式编码值来表示连续记录或计数结束。即使只使用1个字节,也可以有很长的记录长度。
我有一个由Gnu编译器编译的软件,我必须修改它,以便它可以读取由任一编译器生成的未格式化文件,因此它必须检测找到的格式。读取英特尔编译器生成的未格式化文件(遵循“旧”IBM时代)需要“永远”“使用Gnu的fgetc或以流模式打开文件。将文件转换为Gnu所期望的结果将使速度提高100倍。它取决于你的文件大小,如果你想麻烦检测和转换与否。我将程序启动时间(打开一个大的未格式化文件)从5分钟减少到10秒。如果用户想将文件恢复到英特尔编译的程序中,我必须添加选项以重新转换。这是一个痛苦的过程,但你可以继续。

作为一个小提示,有些编译器,如Gfortran和Intel Fortran,尽管有4字节的记录标记,但通过使用子记录支持大于2 GB的记录。更改了标题,因为我真的不喜欢“二进制”这一术语的误导性用法。二进制表示基数2,它与您的问题没有直接联系。在某种程度上,计算机上几乎所有的东西都是二进制的。现在这是一个常见的术语,但fortran的“unmatted”更接近。。。这似乎是重复的,你能不能不要把你的问题贴多次?你所说的只适用于“顺序”access@steabert:这是最常用的(99.999%)。我的代码中大约有一半使用“直接”访问,因此对我来说只有50%:P