读取和覆盖相同的文件

时间:2018-03-26 18:19:30

标签: matrix file-io fortran netcdf

因此,我的代码的目标是从多个NetCDF文件创建累积矩阵。我希望代码检查初始累积矩阵(cp)应该都是0.0s。如果矩阵已经存在,它将从命令行获取文件和路径,并将NetCDF文件中的值添加到结束矩阵。

! First loop creates an array in initalize.dat full of 0's if no file
    if (does_exist == 0) then
      open (unit=1, file=output_file, status='new')
      cp = 0.0
        do j = 1,168
          write(1, 10) (cp(i,j), i=1,77)
        enddo
      close(1)

10  format(1x, 77(f10.4))

! Since initalize.dat exists, we want to read it
    else
      open(unit=1, file=output_file, status='old', action='readwrite')
        do j = 1,168
          read(1,10) (cp(i,j), i=1,77)
        enddo
      RAINRATE = RAINRATE * 3600.0
      cp = cp + RAINRATE
        do j = 1,168
          write(1,10) (cp(i,j), i=1,77)
        enddo
      close(1)
    print *,"*** SUCCESS reading file ", input_file, "! "
    endif

我遇到的问题是在添加矩阵后用新值替换最终矩阵的值。它不是覆盖所有数据,而是将其添加到数据文件的底部(它应该是168行,最后是336行)。我无法弄清楚造成这种情况的原因是因为我在任何地方都没有position=append。该阵列中的某些值最终也是负值,这是不可能的,因为它们具有降水值。

2 个答案:

答案 0 :(得分:4)

最简单的方法是对文件执行rewind。这是一个小例子:

program overwrite

    implicit none

    character(len=*), parameter :: f = 'matrix.txt'
    integer, parameter :: nrows = 4, ncols = 3
    character(len=*), parameter :: fmt = '(3I5)'
    integer :: u        ! Unit number of the file I/O
    logical :: f_exists ! Whether the file exists
    integer :: matrix(nrows, ncols) ! The actual data

    inquire(file=f, exist=f_exists)

    if ( f_exists ) then
        open(newunit = u, file = f, action='readwrite', &
            status='old', form='formatted')
        read(u, *) matrix  ! Reads values over multiple lines
                           ! until matrix is completely filled.
        rewind(u)
    else
        open(newunit = u, file = f, action='write', &
            status='new', form='formatted')
        matrix = 0
    end if

    matrix = matrix + 1
    write(u, fmt) matrix   ! Writes matrix 3 values per row (see the
                           ! format) until everything's written.

    close(u)

end program overwrite

答案 1 :(得分:1)

只是为了解释发生了什么并清除你的困惑。

  

“我无法弄清楚造成这种情况的原因是因为我没有   position =追加任何地方。“

当然你没有position="append",但这是无关紧要的,因为你在阅读之前打开它,而不是在写之前。如果您读取数据,请关闭文件并再次打开以进行写入(最好使用position="rewind",但通常没有必要),您将在文件的开头写入并且旧内容将被覆盖。

  open(unit=1, file=output_file, status='old', action='read')
    do j = 1,168
      read(1,10) (cp(i,j), i=1,77)
    enddo
  close(1)
  RAINRATE = RAINRATE * 3600.0
  cp = cp + RAINRATE
  open(1, file=output_file, status='replace', action='write')
    do j = 1,168
      write(1,10) (cp(i,j), i=1,77)
    enddo
  close(1)

它的优点是您在阅读之前不会错误地删除数据。打开包含action="readwrite"的某些数据或未明确指定操作的文件时,我总觉得不安全。

BTW,不要使用小于10的单位,很容易打到预连接的单位。请参阅Why on Fortran code, one should use units bigger than 10?Opening a file on unit 5 or 6。到目前为止,最好使用newunit=