for rec in inh:
читает одну строку за раз - не то, что вы хотите для двоичного файла. Вместо этого читайте 4 байта за раз (с циклом while
и inh.read(4)
) (или считывайте все в память одним вызовом .read()
, затем распаковывайте последовательные 4-байтовые фрагменты). Второй подход является наиболее простым и практичным, если объем используемых данных невелик:
import struct
with open('test.bin', 'rb') as inh:
indata = inh.read()
for i in range(0, len(data), 4):
pos = struct.unpack('i', data[i:i+4])
print(pos)
Если вы боитесь потенциально огромных объемов данных (которые занимают больше памяти, чем у вас есть), простой генератор предлагает элегантную альтернативу:
import struct
def by4(f):
rec = 'x' # placeholder for the `while`
while rec:
rec = f.read(4)
if rec: yield rec
with open('test.bin', 'rb') as inh:
for rec in by4(inh):
pos = struct.unpack('i', rec)
print(pos)
Ключевым преимуществом этого второго подхода является то, что генератор by4
можно легко настроить (сохраняя спецификации: возвращать данные двоичного файла по 4 байта за раз), чтобы использовать другую стратегию реализации для буферизации, полностью к первому подходу (прочитайте все, затем разложите его), который можно рассматривать как «бесконечную буферизацию» и кодировать:
def by4(f):
data = inf.read()
for i in range(0, len(data), 4):
yield data[i:i+4]
, оставляя «логику приложения» (что делать с этим потоком 4-байтовых блоков) нетронутой и независимой от уровня ввода-вывода (который инкапсулируется в генераторе).