如何覆盖二进制文件的一部分?

问题描述 投票:0回答:1

我想处理一个二进制文件并将结果写入相同格式的新文件中。

我的代码首先复制标头,然后,对于每个数据帧:加载、处理和输出它:

      program main
      use, intrinsic :: iso_fortran_env, only: int32, real32
      implicit none

      integer(kind=int32),dimension(:),allocatable :: header
      real(kind=real32),dimension(:),allocatable :: frame

      integer(kind=int32) nb_frames, frame_sz
      integer i

      allocate(header(256))

      open(unit=1,file='fort.1',access='stream',status='old')
      read(1) header

      frame_sz = header(1)
      nb_frames = header(2)
      allocate(frame(frame_sz))

      open(unit=2,file='fort.2',access='stream',status='new')
      write(2) header

      do i=1,nb_frames
          read(1) frame
C ...     do some computations
          write(2) frame
      enddo

      close(unit=1)

C ... PLACEHOLDER: update the header in the output file (unit #2)

      close(unit=2)
      deallocate(header)
      deallocate(frame)

      end

经过此处理,我需要更新输出文件中的标头。你会怎么做?

fortran
1个回答
0
投票

如果外部文件有定义的位置,则涉及该文件的下一个数据传输语句将从下一个位置开始。您可以使用

rewind
语句将文件定位在其初始点:

rewind(unit)
write(unit=2, ...) ! Transfer starting from the initial point

就覆盖而言,对初始点的写入影响取决于外部文件的访问模式:

  • 写入顺序连接的文件后紧接着写入结束文件记录
  • 直接连接文件的记录被覆盖并且不写入结束文件
  • 流文件的文件存储单元被覆盖,记录不存在

对于顺序连接的文件,效果是截断(后续记录不再被认为存在)。

对于直接访问和流访问,数据传输完成后,对超出文件位置的文件没有影响。

也就是说:如果您有流访问文件,您可以(覆盖)写入任意文件存储单元。你甚至不需要倒带:

write(unit=2, pos=1, ...)

如果您需要在文件中较早的位置写入更多数据,那么您就不走运了:

  • 直接访问文件将遇到记录结束条件
  • 顺序访问文件会被截断
  • 流访问文件将覆盖后续文件存储单元
© www.soinside.com 2019 - 2024. All rights reserved.