I have a list of bytes as integers, which is something like
[120, 3, 255, 0, 100]
How can I write this list to a file as binary?
Would this work?
newFileBytes = [123, 3, 255, 0, 100]
# make file
newFile = open("filename.txt", "wb")
# write to file
newFile.write(newFileBytes)
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
This is exactly what bytearray is for:
newFileByteArray = bytearray(newFileBytes) newFile.write(newFileByteArray)
If you’re using Python 3.x, you can use bytes instead (and probably ought to, as it signals your intention better). But in Python 2.x, that won’t work, because bytes is just an alias for str. As usual, showing with the interactive interpreter is easier than explaining with text, so let me just do that.
Python 3.x:
>>> bytearray(newFileBytes)
bytearray(b'{x03xffx00d')
>>> bytes(newFileBytes)
b'{x03xffx00d'
Python 2.x:
>>> bytearray(newFileBytes)
bytearray(b'{x03xffx00d')
>>> bytes(newFileBytes)
'[123, 3, 255, 0, 100]'
Method 2
Use struct.pack to convert the integer values into binary bytes, then write the bytes. E.g.
newFile.write(struct.pack('5B', *newFileBytes))
However I would never give a binary file a .txt extension.
The benefit of this method is that it works for other types as well, for example if any of the values were greater than 255 you could use '5i' for the format instead to get full 32-bit integers.
Method 3
To convert from integers < 256 to binary, use the chr function. So you’re looking at doing the following.
newFileBytes=[123,3,255,0,100]
newfile=open(path,'wb')
newfile.write((''.join(chr(i) for i in newFileBytes)).encode('charmap'))
Method 4
As of Python 3.2+, you can also accomplish this using the to_bytes native int method:
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'))
I.e., each single call to to_bytes in this case creates a string of length 1, with its characters arranged in big-endian order (which is trivial for length-1 strings), which represents the integer value byte. You can also shorten the last two lines into a single one:
newFile.write(''.join([byte.to_bytes(1, byteorder='big') for byte in newFileBytes]))
Method 5
You can use the following code example using Python 3 syntax:
from struct import pack
with open("foo.bin", "wb") as file:
file.write(pack("<IIIII", *bytearray([120, 3, 255, 0, 100])))
Here is shell one-liner:
python -c $'from struct import packnwith open("foo.bin", "wb") as file: file.write(pack("<IIIII", *bytearray([120, 3, 255, 0, 100])))'
Method 6
Use pickle, like this: import pickle
Your code would look like this:
import pickle
mybytes = [120, 3, 255, 0, 100]
with open("bytesfile", "wb") as mypicklefile:
pickle.dump(mybytes, mypicklefile)
To read the data back, use the pickle.load method
Method 7
Convenient function to write array of int to a file,
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
How to call the function,
write_array("data/filename",[1,2,3,4,5,6,7,8])
And wrap the following in a class for readable encode/decode:
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
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0