2012-01-05 151 views
15

我不明白fortran中无格式文件的格式。Fortran无格式文件格式

例如:

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

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

由于

+2

更改了标题,因为我真的不喜欢误导性的用法 - “二元”。二进制表示基地2,它不直接连接到您的问题。在某种程度上,几乎所有的计算机都是二进制的。这是当今常见的术语,但fortran的“未格式化”更接近。 – Rook 2012-01-07 03:24:55

+1

这里有关流的一些有用的信息... http://www.star.le.ac.uk/~cgp/streamIO.html – Rook 2012-01-07 03:27:57

+1

这似乎是http://stackoverflow.com/questions/8751154/的重复在fortran-on-gnuplot上查看二进制输出,你能不能多次发布你的问题? – steabert 2012-01-11 18:41:17

回答

18

对于未格式化的IO,Fortran编译器通常写记录的长度在记录的开始和结束。大多数但不是全部编译器使用四个字节。这有助于读取记录,例如最后的长度有助于退格操作。您可以使用Fortran 2003的新Stream IO模式来抑制这种情况,Fortran 2003是为了与其他语言兼容而添加的。在您的公开声明中使用access ='stream'

+2

作为次要记录,尽管有4个字节的记录标记,但使用子记录,一些编译器(如Gfortran和Intel Fortran支持记录大于2 GB)仍然存在。 – janneb 2012-01-06 13:31:35

5

Fortran IO是基于记录的,而不是基于流的。每当你通过write()写一些东西时,你不仅会写数据,还会记录该记录的开始和结束标记。两个记录标记都是该记录的大小。这就是为什么在一次写入(一个记录:一个开始标记,一串实际值,一个结束标记)中编写一串实数的原因与在单独写入时写入每个实际的大小不同(每个记录有多个记录一个开始标记,一个真实标记和一个结束标记)。如果你正在写大矩阵,这是非常重要的,因为如果写得不正确,你可能会扩大职业。

+3

你所说的只对'顺序'访问是正确的 – steabert 2012-01-11 18:46:45

+1

@steabert:这是最常用的(99.999%)使用。 – 2012-01-11 21:52:01

+1

大约有一半我的代码使用'直接'访问 - 所以这会让我只有50%:P – mgilson 2013-03-02 02:57:38

6

出于这个确切原因,我从来没有使用具有无格式输出的顺序访问。然而,这取决于应用程序,有时记录长度指示符(特别是非结构化数据)很方便。正如Steiner在Looking at binary output from fortran on gnuplot中建议的那样,您可以通过使用关键字参数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 

请注意,这不是在便携性意义上的理想形式给出。在用直接访问编写的未格式化文件中,没有关于每个元素大小的信息。描述数据大小的自述文本文件对我来说工作很好,我更喜欢这种方法,而不是在顺序模式下进行填充。

0

Fortran Unformatted IO我对使用Intel和Gnu编译器的不同输出非常熟悉。幸运的是,我可以追溯到1970年代IBM的丰富经验让我能够解码事物。 Gnu使用4个字节的整数计数器记录记录长度。英特尔使用1字节计数器和一些嵌入式编码值来表示连续记录或计数结束。即使仅使用1个字节,仍然可以有很长的记录长度。 我有Gnu编译器编译的软件,我必须修改它,以便它可以读取由编译器生成的未格式化的文件,因此它必须检测它找到的格式。阅读由英特尔编译器生成的未格式化文件(遵循“旧”IBM时代),需要使用Gnu的fgetc或以流模式打开文件“永远”。将文件转换为Gnu预期的结果的系数高达100倍如果你想打扰检测和转换,这取决于你的文件大小,我将程序启动时间从5分钟缩短到10秒,我不得不添加一些选项来重新转换如果用户想把文件带回到英特尔编译的程序中,那又回来了。这是一件很痛苦的事情,但是你去了。