Питонов, пишущих двоичный файл

Я использую python 3 Я пытался записать двоичный файл в файл, я использую r + b.

for bit in binary:
    fileout.write(bit)

где binary - список, содержащий числа. Как записать это в файл в двоичном формате?

Конечный файл должен выглядеть так: b 'x07\x08\x07\

Спасибо

Ответ 1

Когда вы открываете файл в двоичном режиме, вы в основном работаете с типом bytes. Поэтому, когда вы пишете файл, вам нужно передать объект bytes, и когда вы его прочитаете, вы получите объект bytes. Напротив, при открытии файла в текстовом режиме вы работаете с объектами str.

Итак, запись "binary" действительно записывает строку байтов:

with open(fileName, 'br+') as f:
    f.write(b'\x07\x08\x07')

Если у вас есть фактические целые числа, которые вы хотите записать как двоичные, вы можете использовать функцию bytes для преобразования последовательности целых чисел в объект байтов:

>>> lst = [7, 8, 7]
>>> bytes(lst)
b'\x07\x08\x07'

Объединяя это, вы можете записать последовательность целых чисел в виде объекта байта в файл, открытый в двоичном режиме.


Как отметил Гипербореус в комментариях, bytes будет принимать только последовательность чисел, которые действительно вписываются в байты, то есть числа от 0 до 255. Если вы хотите хранить произвольные (положительные) целые числа так, как они есть, не зная их точного размера (что требуется для структуры), вы можете легко написать вспомогательную функцию, которая разбивает эти числа на отдельные байты:

def splitNumber (num):
    lst = []
    while num > 0:
        lst.append(num & 0xFF)
        num >>= 8
    return lst[::-1]

bytes(splitNumber(12345678901234567890))
# b'\xabT\xa9\x8c\xeb\x1f\n\xd2'

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

with open(fileName, 'br+') as f:
    for number in numbers:
        f.write(bytes(splitNumber(number)))

Ответ 2

где бинарный список, содержащий числа

Число может иметь тысячу и одно различное двоичное представление (порядковый номер, ширина, 1-дополнение, 2-дополнение, числа с плавающей запятой различной точности и т.д.). Итак, сначала вы должны решить, в каком представлении вы хотите хранить свои номера. Затем вы можете использовать модуль struct для этого.

Например, последовательность байтов 0x3480 может интерпретироваться как 32820 (короткое число без знака с прямым порядком байтов), или -32716 (короткое время без знака с прямым порядком байтов) или 13440 (короткое время с прямым порядком байтов).

Небольшой пример:

#! /usr/bin/python3

import struct

binary = [1234, 5678, -9012, -3456]
with open('out.bin', 'wb') as f:
    for b in binary:
        f.write(struct.pack('h', b)) #or whatever format you need

with open('out.bin', 'rb') as f:
    content = f.read()
    for b in content:
        print(b)
    print(struct.unpack('hhhh', content)) #same format as above

печать

210
4
46
22
204
220
128
242
(1234, 5678, -9012, -3456)