7

I have a string of 1's and 0's in Python and I would like to write it to a binary file. I'm having a lot of trouble with finding a good way to do this.

Is there a standard way to do this that I'm simply missing?

4
  • 2
    The standard way is never to traffic in strings of "1"s and "0"s. Where did these strings come from? Commented Oct 11, 2011 at 21:45
  • 4
    There is not meaningfully such a thing as "a binary file". All files are 'binary'; they contain sequences of bits. It sounds like what you mean is "I want to interpret each '1' and '0' character in the string as a single bit, group sets of 8 bits into bytes, and write the result to file". Commented Oct 11, 2011 at 22:08
  • @KarlKnechtel. Sure, yes, that's what I would like to do. But I'm getting errors when I try do to that, much in the same way as liori suggested below. I've explained the problem a little below. Commented Oct 12, 2011 at 1:11
  • @RussellBorogove. I agree, it's terrible, but it's for an assignment for a course. I wish I had a choice. :) Commented Oct 12, 2011 at 1:11

5 Answers 5

9

If you want a binary file,

>>> import struct
>>> myFile=open('binaryFoo','wb')
>>> myStr='10010101110010101'
>>> x=int(myStr,2)
>>> x
76693
>>> struct.pack('i',x)
'\x95+\x01\x00'
>>> myFile.write(struct.pack('i',x))
>>> myFile.close()
>>> quit()
$ cat binaryFoo
�+$

Is this what you are looking for?

Sign up to request clarification or add additional context in comments.

5 Comments

The limit of possible values of myStr is pretty low ('i' format requires -2147483648 <= number <= 2147483647). You'd have to break it up into smaller values. Regardless, there's not enough information provided in the question to truly answer it.
@oxtopus, Agreed that the range is limited. But what other way would you suggest?
@oxtopus agreed that there's not really enough information, but we all seem to be mind-reading the OP in the same way... :)
It's close, but myStr is really big in my case - about 100000 long. So I get a an error because "an argument is out of range." I'm able to get around that using a buffer, sorta, of length 31, but that's not quite right - my file size in the end is a little bigger than it should be. Chopping my string into substrings of length 32 gives an "argument out of range" error again. Thoughts?
We're not psychic; you're going to have to show (perhaps in a new question) how you are "chopping your string into substrings of length 32" and processing the result.
3
In [1]: int('10011001',2)
Out[1]: 153

Split your input into pieces of eight bits, then apply int(_, 2) and chr, then concatenate into a string and write this string to a file.

Something like...:

your_file.write(''.join(chr(int(your_input[8*k:8*k+8], 2)) for k in xrange(len(your_input)/8)))

2 Comments

This is what I was trying to do, but I get a UnicodeEncodeError when I try to write the string. Apparently, this is because there is some character that is not supported by ascii in the string - but the doc for chr() says it returns only ascii characters. Thoughts?
@sevandyk: is it python 3? is your string of zeros and ones actually a unicode object? do you open your file in a binary mode (open(..., 'wb'))?
2

There is a bitstring module now which does what you need.

from bitstring import BitArray

my_str = '001001111'
binary_file = open('file.bin', 'wb')
b = BitArray(bin=my_str)
b.tofile(binary_file)
binary_file.close()

You can test it from the shell in Linux with xxd -b file.bin

1 Comment

What package contains bitstring? I tried installing it, but I got the error "The following packages are not available from current channels"
1

Or you can use the array module like this

$ python
Python 2.7.2+ (default, Oct  4 2011, 20:06:09) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import random,array
#This is the best way, I could think of for coming up with an binary string of 100000 
>>> binStr=''.join([str(random.randrange(0,2)) for i in range(100000)]) 
>>> len(binStr)
100000
>>> a = array.array("c", binStr)
#c is the type of data (character)
>>> with open("binaryFoo", "ab") as f:
...     a.tofile(f)
... 
#raw writing to file
>>> quit()
$ 

Comments

0
BITS_IN_BYTE = 8
chars = '00111110'
bytes = bytearray(int(chars[i:i+BITS_IN_BYTE], 2)
    for i in xrange(0, len(chars), BITS_IN_BYTE))
open('filename', 'wb').write(bytes)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.