【问题标题】:How to open an external file while a FORTRAN program is running如何在 FORTRAN 程序运行时打开外部文件
【发布时间】:2013-03-14 21:50:22
【问题描述】:

我有一个执行数值积分的 FORTRAN 代码。所有计算的数据都写入外部文件 (data.out)。这是代码的简单草图

OPEN(UNIT=10,FILE='data.out')
DO i=1,n

........

WRITE(10,'(7(E22.16,1x))')a,b,c,d,e,f,g

........

ENDDO
CLOSE(10)

程序会持续运行很长时间(大约 1.5 小时),直到数值积分完成。在执行期间,我想在 .out 文件中查看结果。但是,当我在 .exe 运行时尝试打开 .out 文件时,我收到以下消息: “文档 data.out 被另一个应用程序使用,无法访问。”那么,有没有办法在执行过程中打开 .out 文件呢?观察输出值对我来说很重要(它们不仅仅是上面示例中的 7 个),因此在屏幕输出中发送它们并不方便(显着降低了代码的速度)。 提前谢谢了。


* 编辑 *


这是与上述情况非常相似的另一种情况。在这里,集成例程从输入文件读取初始条件并将输出写入另一个外部文件。下面我给出对应的代码骨架

     OPEN(UNIT=10,FILE='input.par',STATUS='UNKNOWN')
 2   READ(10,*,END=1) x_0,y_0

 !   INTEGRATION LOOP
     DO i=1,n
     ........
     ENDDO

     OPEN(UNIT=12,FILE='data.out')
     WRITE(12,'(7(E22.16,1x))')a,b,c,d,e,f,g

     GOTO 2

 1   CLOSE(10)
     CLOSE(12)

因此,例程打开 UNIT 10 读取初始条件,执行积分,并在积分结束时将输出写入 UNIT 12。然后,它采用另一组初始条件并重复相同的过程,直到它出现在 UNIT 10 中不再是初始条件。同样,我希望能够打开和监视 UNIT 12。我尝试了您的方法,但在这种情况下它不能正常工作。我可以随时打开 UNIT 12,但该例程不会在此处写入所有输出。事实上,它只写入最后一组初始条件的输出。有任何想法吗?我坚信对您的方法稍作修改就可以完成这项工作。

【问题讨论】:

  • @AustinMullins 有什么想法吗?
  • 哪个操作系统?你试过tail 命令吗?
  • 显然是窗口。这个问题的最佳答案是“安装 linux”..
  • 稍微研究了一下——windows确实允许多个进程访问一个文件,但是你需要在打开文件时指定文件共享模式。您可以尝试阅读您的编译器文档,看看是否有一个钩子可以做到这一点。

标签: file-io fortran


【解决方案1】:

除了将结果打印到屏幕上之外,您还可以在每次写入操作后关闭文件并在下一个集成周期中重新打开它以追加新数据。

program test
  implicit none

  integer :: ii

  ! Create emtpy file
  open(10, file='data.out', status='REPLACE', action='WRITE')
  close(10)

  do ii = 1, 100
    !...
    ! Reopen file, append new information and close it again.
    open(10, file='data.out', status='OLD', action='WRITE', position='APPEND')
    write(10,'(7(E23.16,1x))') 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0
    close(10)
  end do

end program test

编辑:主要思想是,在开始任何类型的循环之前,通过第一个 open 语句创建一个空文件:

  open(10, file='data.out', status='REPLACE', action='WRITE')
  close(10)

然后,在循环中,您只需 追加 到该文件,以确保您不会替换已经存在的内容:

open(10, file='data.out', status='OLD', action='WRITE', position='APPEND')
write(10,'(7(E23.16,1x))') 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0
close(10)

请注意传递给open 语句的参数的差异。

【讨论】:

  • 在一些写入操作之后关闭然后重新打开文件可能比在每次写入操作之后更有效。您可能想尝试一下。
  • 非常感谢您的回复。真的行。但是,我有另一种情况(请参阅我的编辑),您的方法不起作用。有什么想法吗?
  • 你应该追加文件,而不是替换它的内容。我刚刚更新了我的帖子以使这个想法更加清晰。如果您没有相应地指定 positionstatus(或者您根本没有指定它们),您的文件将在每个 open 语句中重新创建,内容为空。
  • 非常感谢您的建议。它就像一个魅力!
  • 当心,现在如果您打开该文件查看它,并且碰巧在您的 fortran 重新打开它时仍然打开它,您可能会在 fortran 中引发错误。您应该添加代码来优雅地处理该事件..
【解决方案2】:

执行此操作的合乎逻辑的方法是将输出回显到终端。默认情况下,这是第 6 单元。所以我会将您的输出更改为:

WRITE(6,'(7(E22.16,1x))')a,b,c,d,e,f,g
WRITE(10,'(7(E22.16,1x))')a,b,c,d,e,f,g

试试看。它甚至可以工作。

【讨论】:

  • 一个 * 的 io-unit 指定终端(如果您实际上想要一个整数值,则指定来自 ISO_FORTRAN_ENV 内部模块的 OUTPUT_UNIT)。 6 是否连接到终端取决于编译器(我至少有一个不预连接 6 的编译器)。当可移植选项非常不同时,在程序中引入编译器依赖项是一种倒退。
  • 你可能是对的,伊恩。很久没用 FORTRAN 了。
猜你喜欢
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-11
  • 2013-02-09
  • 2015-10-01
  • 1970-01-01
  • 2016-07-09
相关资源
最近更新 更多