Как получить доступ к единственной записи с неформатированным прямым доступом на Фортране, когда соответствующий RECL не известен?

Если только не использовать потоковый доступ new-ish, доступный в F2003, Фортран классически считает файлы последовательностью записей. Если файл подключен для прямого доступа, можно получить доступ к любой записи в любом порядке, указав номер записи. Например:

open(newunit=funit, file=filename, form='unformatted', access='direct', &
     recl=64, status='old')
read(funit, rec=2) data
close(funit)

Так что это звучит замечательно... однако я не уверен, что понимаю параметр RECL и то, как можно эффективно использовать прямой доступ, если правильная длина записи еще не известна. Из документации (различные версии Intel Fortran):

Все записи имеют длину, указанную параметром RECL в операторе OPEN.

Другими словами, прямой доступ позволяет получить доступ к данным в количестве, равном или меньшем, чем RECL, при этом перемещаясь по файлу с шагом RECL. То есть, вы можете указать любое значение, которое вам нравится (я полагаю, что оно меньше или равно размеру файла). Думаю, это очевидно в ретроспективе... но я надеялся, что соответствующий RECL каким-то образом будет обнаружен. 1 Возможно, я делаю это неправильно, но я хотел бы получить данные только из указанной записи - не больше, не меньше.

Помимо кодирования соответствующего RECL Значение в разделе "заголовок" файла, есть ли способ получить доступ к одной записи за раз с файлом, подключенным для неформатированного (или даже отформатированного) прямого доступа, если правильная длина записи заранее не известна? Какие уловки торговли используются, чтобы сделать это?

1 я надеялся inquire(funit, recl=rl) будет предоставлять соответствующий RECL, но если файл был подключен для прямого доступа, он возвращает значение RECL, указанное при открытии файла. Если подключен для последовательного доступа, кажется, что он возвращает максимально допустимую длину записи (?), 2040 в моем случае.

1 ответ

Решение

На самом деле, невозможно найти его по просмотру файла, потому что это просто данные и (обычно) нет маркеров записи, поэтому компилятор просто видит поток неструктурированных байтов. По крайней мере, в байт-ориентированных компьютерах. Я ничего не знаю о файлово-ориентированных файловых системах, только то, что они существуют.

Если вы знаете, какие данные хранятся в записи прямого доступа, вы можете запросить компилятор, спросив не о файле, а о данных.

Например, если запись состоит из переменных a, b, cкакими бы они ни были,

 !just an example
 real :: a(10)
 type(my_type) :: b
 character(5) :: c(3)

Вы спрашиваете, насколько велика такая запись

 inquire(iolength=rl) a, b, c

а затем вы подключаете свой файл с recl=rl

open(newunit=funit, file=filename, form='unformatted', access='direct', &
     recl=rl, status='old')

См., Например, Почему прямой ввод-вывод некорректно работает с Intel Visual Fortran

Будьте осторожны, значение RECL не переносимо и будет варьироваться в зависимости от компилятора. Некоторые измеряют это в байтах, а некоторые в 4-байтовых словах. Я просто помню, что гфортран и ифорт различаются, а не тот, который есть какой. И мне все равно, кто какой.

Если вы обнаружите, что указали RECL с магической константой, как в recl=64 вы делаете что-то не так, потому что это не будет работать в другом компиляторе. У вас всегда должна быть переменная, а не фиксированное число.

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