Может ли Фортран читать байты напрямую из двоичного файла?

У меня есть двоичный файл, который я хотел бы прочитать с помощью Fortran. Проблема в том, что он был написан не на Фортране, поэтому в нем нет индикаторов длины записи. Так что обычное неформатированное чтение Фортрана работать не будет.

У меня возникла мысль, что я могу быть хитрым и прочитать файл как форматированный файл побайтно (или 4 байта на 4 байта, на самом деле) в массив символов, а затем преобразовать содержимое символов в целые числа и числа с плавающей запятой через передаточная функция или устрашающее утверждение эквивалентности. Но это не работает: я пытаюсь прочитать 4 байта за раз, и, в соответствии с выводом POS из оператора inquire, чтение пропускается примерно 6000 байтов или около того, и массив символов загружается мусором.

Так что это не годится. Есть ли какие-то детали в этом подходе, которые я забываю? Или есть просто принципиально другой и лучший способ сделать это в Фортране? (Кстати, я также пробовал читать массив integer*1 и массив байтов. Несмотря на то, что эти коды компилировались, когда дело доходило до оператора чтения, код ломался.)


person bob.sacamento    schedule 19.07.2012    source источник


Ответы (1)


да.

Fortran 2003 ввел потоковый доступ в язык. До этого большинство процессоров поддерживали что-то эквивалентное в качестве расширения, возможно, называвшееся «двоичным» или аналогичным.

Неформатированный доступ к потоку не накладывает никакой структуры записи на файл. В качестве примера, чтобы прочитать данные из файла, который соответствует одному int в сопутствующем процессоре C (если есть) для конкретного процессора Fortran:

USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
INTEGER, PARAMETER :: unit = 10
CHARACTER(*), PARAMETER :: filename = 'name of your file'
INTEGER(C_INT) :: data
!***
OPEN(unit, filename, ACCESS='STREAM', FORM='UNFORMATTED')
READ (unit) data
CLOSE(unit)
PRINT "('data was ',I0)", data

У вас все еще могут быть проблемы с порядком байтов и размером типа данных, но эти аспекты не зависят от языка.

Если вы пишете в соответствии с языковым стандартом, предшествующим Fortran 2003, тогда может работать неформатированное чтение с прямым доступом в подходящую целочисленную переменную - это зависит от процессора Fortran, но работает для многих текущих процессоров.

person IanH    schedule 19.07.2012
comment
Работает отлично! Спасибо! И я думал, что вот-вот научился хорошо разбираться в FORTRAN 90. А теперь еще чему поучиться! Ах хорошо. Большое спасибо. - person bob.sacamento; 20.07.2012
comment
Без потокового доступа чтение Fortran интерпретировало некоторые данные как информацию о длине записи. Которые пропустили данные, которые вы хотели прочитать, и привели к неправильной длине записи. К тому же в файле действительно нет записей в смысле Фортрана. - person M. S. B.; 20.07.2012
comment
@ M.S.B .: Если, как указал OP, он сначала попробовал отформатированное чтение, я предполагаю, что он сканировал вперед, пока не встретил символ новой строки. - person janneb; 20.07.2012
comment
@janneb, да. При нормальном форматированном чтении Fortran заполняет запрошенную строку, а затем отбрасывает остальную часть записи. Что вы могли бы переопределить, используя форматированный поток ввода-вывода! - person M. S. B.; 20.07.2012
comment
@M. S. B. Непродолжительный ввод - это то, что необходимо, чтобы избежать отбрасывания остальной части записи. Продвижение форматированного потока позиционирует файл после только что прочитанной записи так же, как продвижение форматированного последовательного потока. И форматированный поток, и форматированный последовательный имеют проблемы с возвращением байтовых шаблонов, которые выглядят как новые строки и / или разделители записей. - person IanH; 20.07.2012
comment
Даже несмотря на то, что IanH помог мне решить мою проблему, я дал персонажу прочитать еще один шанс. (Да, у меня немного ОКР.) Кажется, что все работает нормально, побайтовое чтение, пока код не достигнет байта, который он интерпретирует как / n (новая строка). Затем он жалуется, что я пытаюсь прочитать конец записи, и вылетает. Я не собираюсь позволять этому беспокоить меня, но если у кого-то есть дальнейшее понимание, я буду рад выслушать. Спасибо за отличное обсуждение, ребята. - person bob.sacamento; 20.07.2012
comment
Вы не сказали, какой доступ к файлам и какие режимы вы использовали. Если вы использовали форматированный последовательный, то новая строка обычно используется реализациями процессора в качестве маркера конца записи (в форматированном потоке новая строка всегда является концом записи). Следовательно - вы запрашиваете данные, процессор видит конец записи и затем жалуется соответственно. Возможно, вам больше повезет с чтением байтов (символов) из файла с использованием неформатированного прямого доступа, но это зависит от того, как ваш процессор fortran реализует неформатированный прямой доступ. - person IanH; 21.07.2012