чтение неформатированного файла с помощью python

1

У меня есть программа fortran, генерирующая неформатированные файлы, и я пытаюсь их прочитать в Python.

У меня есть исходный код, поэтому я знаю, что первый "кусок" - это массив character*1 name(80) и т.д. Поэтому я начинаю с

f = open(filename,'rb')
bytes = 80
name = struct.unpack('c'*bytes,f.read(bytes))

и name представляет собой кортеж длиной 80 строк, состоящий из строк длиной 1; некоторые из которых являются шестнадцатеричными строками (например, \x00). Как я могу преобразовать эту переменную в одну строку ascii?

  • 0
    Я думаю, что я также должен использовать open(filename,'r') вместо 'rb' .
Теги:
ascii
fortran

2 ответа

6
Лучший ответ

Большинство неформатированных файлов Fortran будут содержать дополнительные байты, чтобы указать длину записи. Запись - это группа элементов, написанных с помощью одного оператора записи Fortran. Обычно 4 байта в начале и конце каждой записи. Поэтому на другом языке вам захочется прочитать эти "скрытые" значения и пропустить их. В этом случае, если вы попытаетесь интерпретировать их как часть вашей строки, вы добавите неверные значения в строку, которые, скорее всего, будут иметь особые значения для ASCII.

Строка Fortran будет фиксированной длиной и заполнена на конце пробелами, которая равна 0x20 в ASCII. Я бы не ожидал значения 0x00, если строка не была инициализирована, или программист Fortran использовал строку для хранения двоичных данных.

В эту эпоху, если программист Fortran пишет неформатированный/двоичный файл, предназначенный для использования с другим языком, они могут привести к тому, что эти дополнительные байты будут опущены с использованием метода "потока" IO для Fortran 2003.

  • 0
    Это было очень полезно, спасибо.
  • 0
    Если у вас есть доступ к исходному коду Fortran, который написал этот файл, вы можете легко проверить и посмотреть, так ли это - если он использует последовательный ввод / вывод (по умолчанию), он будет иметь верхний / нижний колонтитул записи, где, если он указан как прямого доступа не будет. Вы также можете посмотреть на размер файла и вычислить его «ожидаемый» размер на основе того, что, как вы знаете, оно содержит - если оно больше и вы уверены, что получили все, то это, скорее всего, результат этих верхних / нижних колонтитулов записи.
2

Сначала используйте спецификатор формата, а затем отмените нулевые значения.

>>> struct.unpack('%ds' % 20, 'Hello, World!' + '\x00' * 7)
('Hello, World!\x00\x00\x00\x00\x00\x00\x00',)
>>> struct.unpack('%ds' % 20, 'Hello, World!' + '\x00' * 7)[0].rstrip('\x00')
'Hello, World!'
  • 0
    Ах, не знал, что я мог бы использовать этот спецификатор. Я вижу, что \x00 равен NULL, но у меня также есть другие строки, такие как \xa0 , `@ \ x08 и т. Д. ... есть ли конвертер hex-> ascii? Я искал вокруг и нахожу странным, что я не сталкивался ни с одним.
  • 0
    Все, что ниже \ x80, уже является ASCII. Возможно, вам нужно декодировать дальше или решить, что вы смотрите на другой набор символов.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню