Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python writing binary

I use python 3 I tried to write binary to file I use r+b.

for bit in binary:
    fileout.write(bit)

where binary is a list that contain numbers. How do I write this to file in binary?

The end file have to look like b' x07\x08\x07\

Thanks

like image 221
Alon Avatar asked Jan 06 '14 17:01

Alon


People also ask

Can you write binary in Python?

In addition, Python allows you to specify two modes in which a file can be handled― binary and text. Binary mode is used for handling all kinds of non-text data like image files and executable files.

How do you write in binary mode in Python?

In Python, files are opened in text mode by default. To open files in binary mode, when specifying a mode, add 'b' to it.

What is binary format in Python?

"Binary" files are any files where the format isn't made up of readable characters. Binary files can range from image files like JPEGs or GIFs, audio files like MP3s or binary document formats like Word or PDF. In Python, files are opened in text mode by default.

Is .PY a binary file?

Python has tools for working with binary files. Binary files use strings of type bytes. This means when reading binary data from a file, an object of type bytes is returned. The binary file is opened using the open() function, whose mode parameter contains the character 'b'.


2 Answers

When you open a file in binary mode, then you are essentially working with the bytes type. So when you write to the file, you need to pass a bytes object, and when you read from it, you get a bytes object. In contrast, when opening the file in text mode, you are working with str objects.

So, writing “binary” is really writing a bytes string:

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

If you have actual integers you want to write as binary, you can use the bytes function to convert a sequence of integers into a bytes object:

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

Combining this, you can write a sequence of integers as a bytes object into a file opened in binary mode.


As Hyperboreus pointed out in the comments, bytes will only accept a sequence of numbers that actually fit in a byte, i.e. numbers between 0 and 255. If you want to store arbitrary (positive) integers in the way they are, without having to bother about knowing their exact size (which is required for struct), then you can easily write a helper function which splits those numbers up into separate bytes:

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'

So if you have a list of numbers, you can easily iterate over them and write each into the file; if you want to extract the numbers individually later you probably want to add something that keeps track of which individual bytes belong to which numbers.

with open(fileName, 'br+') as f:
    for number in numbers:
        f.write(bytes(splitNumber(number)))
like image 168
poke Avatar answered Sep 21 '22 05:09

poke


where binary is a list that contain numbers

A number can have one thousand and one different binary representations (endianess, width, 1-complement, 2-complement, floats of different precision, etc). So first you have to decide in which representation you want to store your numbers. Then you can use the struct module to do so.

For example the byte sequence 0x3480 can be interpreted as 32820 (little-endian unsigned short), or -32716 (little-endian signed short) or 13440 (big-endian short).

Small example:

#! /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

prints

210
4
46
22
204
220
128
242
(1234, 5678, -9012, -3456)
like image 28
Hyperboreus Avatar answered Sep 20 '22 05:09

Hyperboreus