fortran - 使用 fortran 覆盖文件

标签 fortran fortran90 overwrite

我正在使用写入文件的 Fortran 90 程序。该文件的第一行应该指示剩余文件中的行数。该文件是在满足特定条件且无法事先确定时由程序写入的。基本上,只有在运行结束后,我才会知道总行数。

我想按以下方式进行:

1) 打开文件并在第一行写一些文字,“Hello

2) 根据需要在文件中写入行,并为行数保留一个计数器

3) 运行结束后,就在关闭文件之前,将第一行字符串(“Hello”)替换为计数器

问题出在第3步,不知道如何替换第一行。

我能想到的另一个选择是写入 2 个文件。首先,写一个没有计数器的文件。运行结束后,关闭文件并写入另一个文件,这一次,我知道计数器的值。

我相信有一种方法可以继续第一种方法。有人可以帮我解决这个问题吗?

最佳答案

Fortran 支持三种文件访问形式 - DIRECT、STREAM (F2003+) 和 SEQUENTIAL。 DIRECT 和 STREAM 访问都支持重写文件的较早部分,而 SEQUENTIAL 访问则不支持(对较早记录的重写会在重写记录处截断文件)。

通过直接访问,文件中的所有记录的长度都相同。通过简单地在语句中指定相关记录号,任何输入/输出语句都可以[必须]访问任意记录。但请注意,直接访问文件的典型磁盘格式可能与您对带有“行”的文件的想法不符。

通过格式化流访问,可以使用 INQUIRE 语句捕获文件中的当前位置,然后稍后的输入/输出语句可以使用 POS 说明符在该位置开始数据传输。格式化的流访问文件的典型磁盘格式通常与人们对带行的文本文件的期望相匹配。

流访问可能是您想要的。这两种方法的示例如下所示。

直接访问:

PROGRAM direct
  IMPLICIT NONE

  INTEGER :: unit
  REAL :: r
  INTEGER :: line

  OPEN( NEWUNIT=unit,  &
      FILE='direct.txt',  &
      STATUS='REPLACE',  &
      ACCESS='DIRECT',  &
      RECL=15,  &      ! The fixed record length.
      FORM='FORMATTED' )

  CALL RANDOM_SEED()

  ! No need to write records in order - we just leave off 
  ! writing the first record until the end.

  line = 0
  DO
    CALL RANDOM_NUMBER(r)
    IF (r < 0.05) EXIT

    line = line + 1
    PRINT "('Writing line ',I0)", line
    ! All the "data" records are offset by one, to allow the 
    ! first record to record the line count.
    WRITE (unit, "('line ',I10)", REC=line+1) line
  END DO

  ! Now update the first record with the number of following "lines".
  WRITE (unit, "(I10)", REC=1) line

  CLOSE(unit)
END PROGRAM direct

流访问:

PROGRAM stream
  IMPLICIT NONE

  INTEGER :: unit
  REAL :: r
  INTEGER :: line
  INTEGER :: pos

  OPEN( NEWUNIT=unit,  &
      FILE='stream.txt',  &
      STATUS='REPLACE',  &
      ACCESS='STREAM',  &
      POSITION='REWIND',  &
      FORM='FORMATTED' )

  CALL RANDOM_SEED()

  ! Remember where we are.  In this case, the position 
  ! is the first file storage unit in the file, but 
  ! it doesn't have to be.
  INQUIRE(unit, POS=pos)

  ! Leave some space in the file for later overwriting 
  ! with the number of lines.  We'll stick the number 
  ! zero in there for now.
  WRITE (unit, "(I10)") 0

  ! Write out the varying number of lines.
  line = 0
  DO
    CALL RANDOM_NUMBER(r)
    IF (r < 0.05) EXIT

    line = line + 1
    PRINT "('Writing line ',I0)", line
    WRITE (unit, "('line ',I10)") line
  END DO

  ! Now update the space at the start with the number of following "lines".
  WRITE (unit, "(I10)", POS=pos) line

  CLOSE(unit)
END PROGRAM stream

关于fortran - 使用 fortran 覆盖文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38176611/

相关文章:

fortran - 为什么我应该在 Fortran 中使用 "use, only"

io - 将未格式化(二进制数据)写入标准输出

fortran - 使用 openmp 和可分配数组在 fortran 中循环

node.js - Gulp 可以覆盖所有的 src 文件吗?

c - 通过随机重命名覆盖 Windows 中的文件失败

types - 使用 gfortran 强制显式变量声明

memory - allocate 语句的顺序或语法会影响性能吗? (Fortran)

arrays - Fortran 90 中 double 的最大数组大小是多少?

linux - 寻找丢失的共享库

MySQL 导出到 outfile 并覆盖