#fortran
#c #fortran #fortran77
Вопрос:
У меня есть неформатированный двоичный файл f77. Я знаю, что файл содержит 2 числа с плавающей запятой и длинное целое число, а также данные. Размер файла составляет 536870940 байт, который должен включать 512 ^ 3 значения данных с плавающей запятой вместе с 2 числами с плавающей запятой и длинным целым числом. Значения данных с плавающей запятой 512 ^ 3 составляют 536870912 байт, оставляя еще 28 байт.
Моя проблема в том, что мне нужно определить, где начинаются 28 байтов и как пропустить этот объем памяти, чтобы я мог напрямую обращаться к данным.
Я предпочитаю использовать C для доступа к файлу.
Комментарии:
1. Если
f77
для Fortran, то я действительно не понимаю, почему он помечен C. Последнее предложение не оправдывает его.2. Двоичный файл представляет собой неформатированный двоичный файл fortran. Я получаю доступ к данным на C, а не на fortran.
3. Fortran не определяет формат так называемых «неформатированных» файлов. Существует несколько распространенных вариантов, но вам нужно знать, какая реализация Fortran написала его, возможно, с какими опциями, или же выполнить некоторую судебную экспертизу. Также может иметь значение, какая конкретная последовательность операторов вывода использовалась для записи содержимого.
4. Однажды, несколько десятилетий назад, у меня была похожая проблема — чтение неформатированного двоичного файла Fortran в программу на C. После нескольких дней ударов головой о стену я, наконец, закончил писать процедуру ввода на Fortran и вызывать ее из C. У вас нет документации, чтобы сообщить вам, где появляется рассматриваемая последовательность? Вы знаете, что это либо в начале, либо в конце (а не где-то посередине)?
5. По этому поводу уже есть много вопросов и ответов.
Ответ №1:
К сожалению, не существует стандарта, что unformatted
означает. Но некоторые методы более распространены, чем другие.
Во многих версиях Fortran, которые я использовал, каждая write
команда записывает заголовок (часто unsigned int 32) с указанием количества байтов данных, затем данные, а затем повторяет значение заголовка на случай, если вы читаете сзади.
Из предоставленных вами значений может получиться что-то вроде этого:
- uint32(заголовок record1), вероятно, 12.
- float32, float32, int32 (три «других значения», о которых вы говорили)
- uint32 (заголовок record1, такой же, как первое значение)
- uint32 (заголовок record2, вероятно, 512 ^ 3 * 4)
- float32*512 ^3
- uint32 (заголовок record2, такой же, как и раньше)
Возможно, вам придется проверить порядковый номер.
Поэтому я предлагаю вам открыть файл в программе hexdump и проверить, идентичны ли байты 0-3 байтам 16-19 и повторяются ли байты 20-23 в конце данных снова.
Если это так, я попытаюсь проверить порядковый номер, чтобы увидеть, являются ли значения маленьким или большим порядковым номером, и, если повезет, у вас будут ваши данные.
Примечание: я предполагаю, что эти три других значения являются метаданными о данных и, следовательно, будут находиться в начале файла. Если это не так, они могут быть у вас в конце.
Обновить:
В своем комментарии вы пишете, что ваши данные начинаются примерно с этого:
0C 00 00 00 XX XX XX XX XX XX XX XX XX XX XX XX 0C 00 00 00
^- header-^ ^-header -^
E8 09 FF 1F (many, many values) E8 09 FF 1F
^- header-^ ^--- your data ---^ ^-header -^
Теперь я не знаю, как читать данные в C. Я оставляю это на ваше усмотрение. Что вам нужно сделать, это пропустить первые 24 байта, затем прочитать данные как (возможно, с небольшим порядковым номером) 4-байтовые значения с плавающей запятой. У вас останется 4 байта, которые вам больше не нужны.
Важное примечание: Fortran хранит массивы по столбцам, C afaik хранит их по строкам. Поэтому имейте в виду, что порядок индексов будет обратным.
Я знаю, как прочитать это на Python:
from scipy.io import FortranFile
ff = FortranFile('data.dat', 'r', '<u4')
# read the three values you are not interested in
threevals = ff.read_record('<u4')
# read the data
data = ff.read_record('<f4')
ff.close()
Комментарии:
1. chw21: Это очень интересно. Для позиций 0-7 я вижу 0C 00 00 00 00 00 00 00 00, хотя позиции 5-7 не имеют тех же значений, что и 1-4 при выборе. Позиции 16-19 повторяют 0-3. Как вы указали, позиции 20-23 повторяются в конце файла. Но скажите мне, что все это значит? Почему повторяющийся шаблон не наблюдается во всем файле, если он был повторен хотя бы один раз.