Как перезаписать часть двоичного файла?

Я хочу обработать двоичный файл и записать результаты в новый того же формата.

Мой код начинается с копирования заголовка и для каждого кадра данных его загрузки/обработки/вывода:

      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 ...     some calculations
          write(2) frame
      enddo

      close(unit=1)

C ... PLACEHOLDER: update a few values in the header of unit #2

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

      end

После обработки всего входного файла мне нужно обновить заголовок в выходном файле. Как бы вы это сделали?

Вы можете использовать нестандартный (расширение gnu) call fseek(file_unit, 0, 0, ierr) gfortran, чтобы вернуть указатель позиции файла в начало файла и снова записать заголовок. другие реализации Фортрана могут иметь аналогичные расширения.

Ghorban M. Tavakoly 26.04.2024 18:12

@GhorbanM.Tavakoly записывает ли новый заголовок после fseeking усечение файла (т. е. данные после потери заголовка)?

Fravadona 26.04.2024 18:48

нет. он просто перезаписывает заголовок. см. gcc.gnu.org/onlinedocs/gfortran/FSEEK.html

Ghorban M. Tavakoly 26.04.2024 18:59

Можете ли вы объяснить формат заголовка? (Это не обязательно должно быть точно, но если, например, заголовок не фиксированного размера, влияние будет огромным.)

francescalus 26.04.2024 19:06

Однако, поскольку ваш файл подключен для потокового доступа, нет смысла использовать ерунду вроде нестандартных операторов позиционирования файла: write(..., pos=...).

francescalus 26.04.2024 19:12

@francescalus заголовок имеет фиксированный размер 1024 байта и может иметь необязательные поля; Я не буду добавлять или удалять какие-либо из этих полей.

Fravadona 26.04.2024 19:59

@francescalus, спасибо, попробую write( ..., pos=...) позже.

Fravadona 26.04.2024 20:00

+1 за отдельный пост @francescalus в качестве ответа на этот пост. rewind написан в стандартном формате Fortran 2003 (раздел 9.7.3) и предпочтительнее моего предложения fseek.

Ghorban M. Tavakoly 26.04.2024 21:14

+1 за отдельный пост @francescalus в качестве ответа на этот пост. rewind написан в стандартном формате Fortran 2003 (раздел 9.7.3) и предпочтительнее моего предложения fseek.

Ghorban M. Tavakoly 26.04.2024 21:15

О каком объеме данных вы говорите — о нескольких К или Гигабайтах? Если данных немного, то просто проделайте все манипуляции с памятью, а потом все выпишите в конце.

cup 27.04.2024 08:06

@cup Размер этих файлов может сильно различаться; от нескольких сотен МБ до нескольких десятков ГБ.

Fravadona 27.04.2024 14:08
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
11
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если внешний файл имеет определенную позицию, следующий оператор передачи данных, включающий этот файл, начинается со следующей позиции. Вы можете разместить файл в исходной точке, используя оператор rewind:

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

С точки зрения перезаписи, влияние записи в файл, расположенный в его начальной или другой точке, зависит от режима доступа внешнего файла:

  • за записью в последовательно подключенный файл может последовать неявная запись записи конечного файла.
  • записи для файла, подключенного напрямую, перезаписываются, и нет опасности, что будет записана запись конечного файла.
  • единицы хранения файлов потокового файла перезаписываются и записи не существуют

Для последовательно подключенного файла эффектом записи конечного файла является усечение (последующие записи больше не считаются существующими).

Все это означает: если у вас есть файл потокового доступа, вы можете (пере)записывать произвольные единицы хранения файлов. Вам даже не нужно перематывать назад:

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

Если вам нужно записать больше данных в более раннем месте файла, вам не повезло:

  • файл прямого доступа достигнет состояния конца записи
  • файл доступа к потоку перезапишет последующие единицы хранения файлов

Другие вопросы по теме