Fortran 未格式化文件中出现意外"padding"



我不理解Fortran中未格式化文件的格式。

例如:

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

将矩阵的一列输出到文件中。我发现它在文件的两端都填充了4个字节,但我真的不明白为什么,也不知道如何控制这种行为。有没有办法去掉衬垫?

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

正是因为这个原因,我从未对未格式化的输出使用顺序访问。然而,这取决于应用程序,有时有一个记录长度指示器(尤其是对于非结构化数据)很方便。正如steabert在查看gnuplot上fortran的二进制输出中所建议的那样,您可以通过使用关键字参数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是基于记录的,而不是基于流的。每次通过write()写入内容时,不仅要写入数据,还要写入该记录的开始和结束标记。两个记录标记都是该记录的大小。这就是为什么在一次写入中写入一组实数(一个记录:一个开始标记,一组实数,一个结束标记)与在单独写入中写入每个实数(多个记录,每个记录有一个开始标志,一个实数和一个结束标记)具有不同大小的原因。如果你在写大矩阵,这一点非常重要,因为如果写得不正确,你可能会夸大这个职业。

Fortran非格式化IO我非常熟悉使用英特尔和Gnu编译器的不同输出。幸运的是,我可以追溯到20世纪70年代IBM的丰富经验使我能够解码事物。Gnu用4字节整数计数器填充记录,给出记录长度。英特尔使用一个1字节计数器和一些嵌入的编码值来表示连续记录或计数的结束。即使只使用了1个字节,仍然可以有很长的记录长度。我有Gnu编译器编译的软件,我必须修改它,这样它就可以读取任何一个编译器生成的未格式化文件,所以它必须检测它找到的格式。使用Gnu的fgetc或以流模式打开文件,读取英特尔编译器生成的未格式化文件(遵循"旧的"IBM时代)需要"永远"的时间。将文件转换为Gnu所期望的速度会快100倍。这取决于你的文件大小,你是否想麻烦检测和转换。我减少了程序启动时间(打开一个未格式化的大文件)从5分钟到10秒。如果用户想将文件带回英特尔编译的程序,我必须添加选项以再次重新转换。这一切都很痛苦,但你去吧。

相关内容

  • 没有找到相关文章

最新更新