Python:由1和0组成的字符串 -> 二进制文件

7

我在Python中有一串由 1 和 0 组成的字符串,我想将其写入二进制文件。我正在寻找一个好的方法来完成这个任务。

是否有标准的方法可以做到这一点,只是我不知道而已?


2
标准的方法从来不是处理由"1"和"0"组成的字符串。这些字符串从哪里来? - Russell Borogove
4
“二进制文件”这个说法没有实际意义。所有的文件都是“二进制”的,它们包含一连串比特位。根据你的描述,听起来你想表达的是:“我想把字符串中的每个‘1’和‘0’字符解释为一个单独的比特位,将8个比特位组合成字节,并将结果写入文件”。 - Karl Knechtel
@KarlKnechtel。好的,没错,那就是我想做的。但是当我尝试这样做时,我会遇到错误,就像liori在下面建议的那样。我已经在下面简要解释了问题。 - sevandyk
@RussellBorogove。我同意,这很糟糕,但这是一门课程的作业要求。我希望我有选择的余地。 :) - sevandyk
5个回答

9
如果你需要一个二进制文件,
>>> 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
�+$

这是您在寻找的内容吗?

我的字符串可能值的限制相当低('i'格式要求-2147483648 <= 数字 <= 2147483647)。你需要将它分成更小的值。无论如何,问题中提供的信息不足以真正回答它。 - Austin Marshall
@oxtopus,同意范围有限的观点。但您还有其他建议吗? - Lelouch Lamperouge
@oxtopus同意说,信息实在太少了,但我们所有人似乎都以相同的方式来猜测OP的想法... :) - Karl Knechtel
很接近了,但是在我的情况下myStr非常大——大约有100000个字符。因此我会收到一个“参数超出范围”的错误。我可以使用长度为31的缓冲区来解决这个问题,但这并不完全正确——最终我的文件大小比应该的要大一些。将字符串分割成长度为32的子字符串会再次出现“参数超出范围”的错误。你有什么想法吗? - sevandyk
我们不是通灵的,你需要展示(也许在一个新问题中)如何“将你的字符串切成长度为32的子串”并处理结果。 - Karl Knechtel

3
In [1]: int('10011001',2)
Out[1]: 153

将输入按8位分成多个部分,然后应用 int(_, 2)chr,再将它们连接成一个字符串并将该字符串写入文件。

类似于以下示例:

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

这就是我想要做的事情,但是当我尝试写入字符串时,我遇到了UnicodeEncodeError。显然,这是因为字符串中有一些字符不受ascii支持 - 但是chr()的文档说它仅返回ascii字符。你有什么想法? - sevandyk
@sevandyk:这是Python 3吗?你的0和1字符串实际上是一个Unicode对象吗?你在二进制模式下打开文件(open(..., 'wb'))了吗? - liori

2

现在有一个位字符串模块可以满足你的需求。

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

您可以在Linux的shell中使用xxd -b file.bin来进行测试。


哪个软件包包含bitstring?我尝试安装它,但是出现了错误“当前渠道中没有以下软件包”。 - Braden Brown

1

或者你可以像这样使用array模块

$ 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()
$ 

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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接