我有布尔值的字符串,我想创建一个使用这些布尔值作为位二进制文件。 这是我在做什么:
# first append the string with 0s to make its length a multiple of 8
while len(boolString) % 8 != 0:
boolString += '0'
# write the string to the file byte by byte
i = 0
while i < len(boolString) / 8:
byte = int(boolString[i*8 : (i+1)*8], 2)
outputFile.write('%c' % byte)
i += 1
但是,这在时间产生输出1字节和缓慢。 这将是一个更有效的方式来做到这一点?
Answer 1:
如果先计算出你的所有字节,然后将它们全部写起来应该更快。 例如
b = bytearray([int(boolString[x:x+8], 2) for x in range(0, len(boolString), 8)])
outputFile.write(b)
我还使用一个bytearray
是一种天然的容器来使用,也可以直接写入到文件。
当然你也可以使用库,如果这是适当的,如bitarray和比特串 。 使用后,你可以只说
bitstring.Bits(bin=boolString).tofile(outputFile)
Answer 2:
这里是另一种答案,这个时候使用从工业强度的效用函数PyCrypto - Python的加密工具包 ,其中,在2.6版本(目前最新的稳定版本),它定义pycrypto-2.6/lib/Crypto/Util/number.py
。
前述它的评论说:
Improved conversion functions contributed by Barry Warsaw, after careful benchmarking
import struct
def long_to_bytes(n, blocksize=0):
"""long_to_bytes(n:long, blocksize:int) : string
Convert a long integer to a byte string.
If optional blocksize is given and greater than zero, pad the front of the
byte string with binary zeros so that the length is a multiple of
blocksize.
"""
# after much testing, this algorithm was deemed to be the fastest
s = b('')
n = long(n)
pack = struct.pack
while n > 0:
s = pack('>I', n & 0xffffffffL) + s
n = n >> 32
# strip off leading zeros
for i in range(len(s)):
if s[i] != b('\000')[0]:
break
else:
# only happens when n == 0
s = b('\000')
i = 0
s = s[i:]
# add back some pad bytes. this could be done more efficiently w.r.t. the
# de-padding being done above, but sigh...
if blocksize > 0 and len(s) % blocksize:
s = (blocksize - len(s) % blocksize) * b('\000') + s
return s
Answer 3:
您可以将布尔字符串转换为long
使用data = long(boolString,2)
长那么写这个磁盘可以使用:
while data > 0:
data, byte = divmod(data, 0xff)
file.write('%c' % byte)
然而,没有必要进行布尔字符串。 这是很容易使用long
。 的long
类型可以包含比特的无限数量。 使用位操作,您可以设置或根据需要清除位。 然后,你可以写长到磁盘作为一个整体在一个写操作。
Answer 4:
您可以使用试试这个代码数组类:
import array
buffer = array.array('B')
i = 0
while i < len(boolString) / 8:
byte = int(boolString[i*8 : (i+1)*8], 2)
buffer.append(byte)
i += 1
f = file(filename, 'wb')
buffer.tofile(f)
f.close()
Answer 5:
甲辅助类 (如下所示)可以很容易:
class BitWriter:
def __init__(self, f):
self.acc = 0
self.bcount = 0
self.out = f
def __del__(self):
self.flush()
def writebit(self, bit):
if self.bcount == 8 :
self.flush()
if bit > 0:
self.acc |= (1 << (7-self.bcount))
self.bcount += 1
def writebits(self, bits, n):
while n > 0:
self.writebit( bits & (1 << (n-1)) )
n -= 1
def flush(self):
self.out.write(chr(self.acc))
self.acc = 0
self.bcount = 0
with open('outputFile', 'wb') as f:
bw = BitWriter(f)
bw.writebits(int(boolString,2), len(boolString))
bw.flush()
Answer 6:
使用struct
封装 。
这可以在处理存储在文件中或从网络连接,其他来源中的二进制数据被使用。
编辑:
用一个例子?
作为格式字符为bool
。
import struct
p = struct.pack('????', True, False, True, False)
assert p == '\x01\x00\x01\x00'
with open("out", "wb") as o:
o.write(p)
让我们来看看这个文件:
$ ls -l out
-rw-r--r-- 1 lutz lutz 4 Okt 1 13:26 out
$ od out
0000000 000001 000001
000000
读它再次:
with open("out", "rb") as i:
q = struct.unpack('????', i.read())
assert q == (True, False, True, False)
文章来源: Write boolean string to binary file?