Python hoe naar een binair bestand te schrijven?

Ik heb een lijst met bytes als gehele getallen, wat zoiets is als

[120, 3, 255, 0, 100]

Hoe kan ik deze lijst als binair naar een bestand schrijven?

Zou dit werken?

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

Antwoord 1, autoriteit 100%

Dit is precies waar bytearrayvoor is:

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

Als je Python 3.x gebruikt, kun je in plaats daarvan bytesgebruiken (en dat zou ook moeten, omdat het je bedoeling beter aangeeft). Maar in Python 2.x zal dat niet werken, omdat bytesslechts een alias is voor str. Zoals gewoonlijk is tonen met de interactieve tolk gemakkelijker dan uitleggen met tekst, dus laat me dat gewoon doen.

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]'

Antwoord 2, autoriteit 24%

Gebruik struct.packom de integerwaarden om te zetten in binaire bytes, schrijf dan de bytes. Bijv.

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

Ik zou een binair bestand echter nooit de extensie .txtgeven.

Het voordeel van deze methode is dat deze ook voor andere typen werkt, bijvoorbeeld als een van de waarden groter is dan 255, kunt u in plaats daarvan '5i'gebruiken voor het formaat om de volledige 32 te krijgen -bit gehele getallen.


Antwoord 3, autoriteit 9%

Om te converteren van gehele getallen < 256 naar binair, gebruik de functie chr. U wilt dus het volgende doen.

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

Antwoord 4, autoriteit 9%

Vanaf Python 3.2+ kunt u dit ook bereiken met de to_bytesnative int-methode:

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'))

Dwz, elke afzonderlijke oproep naar to_bytescreëert in dit geval een string met lengte 1, met de karakters gerangschikt in big-endian-volgorde (wat triviaal is voor strings met lengte-1), die de integerwaarde bytevertegenwoordigt. Je kunt de laatste twee regels ook inkorten tot één regel:

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

Antwoord 5, autoriteit 6%

U kunt het volgende codevoorbeeld gebruiken met de Python 3-syntaxis:

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

Hier is shell one-liner:

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

Antwoord 6

Handige functie om een array van int naar een bestand te schrijven,

def write_array(fname,ray):
    '''
    fname is a file pathname
    ray is an array of int
    '''
    print("write:",fname)
    EncodeInit()
    buffer = [ encode(z) for z in ray ]
    some = bytearray(buffer)
    immutable = bytes(some)
    with open(fname,"wb") as bfh:
        wc = bfh.write(immutable)
        print("wrote:",wrote)
    return wc

Hoe de functie aan te roepen,

write_array("data/filename",[1,2,3,4,5,6,7,8])

En verpak het volgende in een klasse voor leesbare codering/decodering:

Encode = {}
Decode = {}
def EncodeInit():
    '''
    Encode[] 0:62 as 0-9A-Za-z
    Decode[] 0-9A-Za-z as 0:62
    '''
    for ix in range( 0,10): Encode[ix] = ix+ord('0')
    for ix in range(10,36): Encode[ix] = (ix-10)+ord('A')
    for ix in range(36,62): Encode[ix] = (ix-36)+ord('a')
    for ix in range( 0,10): Decode[ix+ord('0')] = ix
    for ix in range(10,36): Decode[(ix-10)+ord('A')] = ix
    for ix in range(36,62): Decode[(ix-36)+ord('a')] = ix
def encode(x):
    '''
    Encode[] 0:62 as 0-9A-Za-z
    Otherwise '.'
    '''
    if x in Encode: return Encode[x]
    # else: error
    return ord('.')
def decode(x):
    '''
    Decode[] 0-9A-Za-z as 0:62
    Otherwise -1
    '''
    if x in Decode: return Decode[x]
    # else: error
    return -1

Antwoord 7

Gebruik Pickle, zoals deze: importeer pickle

Uw code zou er als volgt uitzien:

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

Gebruik de Pickle. Load-methode

om de gegevens terug te lezen,

Other episodes