Python, как писать в двоичный файл?

У меня есть список байтов как целых чисел, что-то вроде

[120, 3, 255, 0, 100]

Как я могу записать этот список в файл как двоичный?

Будет ли это работать?

newFileBytes = [123, 3, 255, 0, 100]
# make file
newFile = open("filename.txt", "wb")
# write to file
newFile.write(newFileBytes)

Ответ 1

Это именно то, что bytearray для:

newFileByteArray = bytearray(newFileBytes)
newFile.write(newFileByteArray)

Если вы используете Python 3.x, вы можете использовать bytes вместо этого (и, вероятно, должны, так как он сигнализирует о вашем намерении лучше). Но в Python 2.x это не сработает, потому что bytes является просто псевдонимом для str. Как обычно, показывать с помощью интерактивного интерпретатора проще, чем объяснять с помощью текста, поэтому позвольте мне просто сделать это.

Python 3.x:

>>> bytearray(newFileBytes)
bytearray(b'{\x03\xff\x00d')
>>> bytes(newFileBytes)
b'{\x03\xff\x00d'

Python 2.x:

>>> bytearray(newFileBytes)
bytearray(b'{\x03\xff\x00d')
>>> bytes(newFileBytes)
'[123, 3, 255, 0, 100]'

Ответ 2

Используйте struct.pack, чтобы преобразовать целочисленные значения в двоичные байты, а затем записать байты. Например.

newFile.write(struct.pack('5B', *newFileBytes))

Однако я бы никогда не дал двоичный файл расширения .txt.

Преимущество этого метода заключается в том, что он работает и для других типов, например, если какое-либо из значений было больше 255, вы могли бы использовать '5i' для формата вместо этого, чтобы получить полные 32-битные целые числа.

Ответ 3

Для преобразования из целых чисел < 256 в двоичный код, используйте функцию chr. Итак, вы смотрите на следующее.

newFileBytes=[123,3,255,0,100]
newfile=open(path,'wb')
newfile.write((''.join(chr(i) for i in newFileBytes)).encode('ascii'))

Ответ 4

Вы можете использовать следующий пример кода, используя синтаксис Python 3:

from struct import pack
with open("foo.bin", "wb") as file:
  file.write(pack("<IIIII", *bytearray([120, 3, 255, 0, 100])))

Вот однострочный оболочка оболочки:

python -c $'from struct import pack\nwith open("foo.bin", "wb") as file: file.write(pack("<IIIII", *bytearray([120, 3, 255, 0, 100])))'

Ответ 5

С Python 3.2+ вы также можете выполнить это, используя метод to_bytes:

newFileBytes = [123, 3, 255, 0, 100]
# make file
newFile = open("filename.txt", "wb")
# write to file
for byte in newFileBytes:
    newFile.write(byte.to_bytes(1, byteorder='big'))

Т.е. каждый раз при вызове to_bytes в этом случае создается строка длиной 1, а ее символы расположены в формате big-endian порядок (который тривиален для строк длины-1), который представляет собой целочисленное значение byte. Вы также можете сократить две последние строки до одной:

newFile.write(''.join([byte.to_bytes(1, byteorder='big') for byte in newFileBytes]))

Ответ 6

Используйте рассол, например: import pickle

Ваш код будет выглядеть так:

import pickle
mybytes = [120, 3, 255, 0, 100]
with open("bytesfile", "wb") as mypicklefile:
    pickle.dump(mybytes, mypicklefile)

Чтобы прочитать данные назад, используйте метод pickle.load