我在Python中有一个字符串(它也可能是一个整数),我想将它写入文件。它只包含1和0我想要将1和0的模式写入文件。我想直接编写二进制文件,因为我需要存储大量数据,但只需要存储某些值。当我只需要三个时,我认为没有必要占用每个值使用8位的空间。
例如。假设我要将二进制字符串"01100010"
写入文件。如果我在文本编辑器中打开它,它会说b
(01100010是b的ascii代码)。不要混淆。我不想写ascii代码,这个例子只是为了表明我想直接将字节写入文件。
澄清:
我的字符串看起来像这样:
binary_string = "001011010110000010010"
它不是由数字或字符的二进制代码组成。它包含仅与我的程序有关的数据。
答案 0 :(得分:8)
要写出字符串,您可以使用文件的.write
方法。要写一个整数,您需要使用struct
模块
import struct
#...
with open('file.dat', 'wb') as f:
if isinstance(value, int):
f.write(struct.pack('i', value)) # write an int
elif isinstance(value, str):
f.write(value) # write a string
else:
raise TypeError('Can only write str or int')
但是,int和string的表示形式不同,您可以使用bin
函数将其转换为0和1的字符串
>>> bin(7)
'0b111'
>>> bin(7)[2:] #cut off the 0b
'111'
但也许处理所有这些int
的最佳方法是确定文件中二进制字符串的固定宽度并将其转换为:
>>> x = 7
>>> '{0:032b}'.format(x) #32 character wide binary number with '0' as filler
'00000000000000000000000000000111'
答案 1 :(得分:6)
好的,经过相当多的搜索,我找到了答案。我相信你们其他人根本就不明白(这可能是我的错,因为我必须编辑两次才能说清楚)。我找到了here。
答案是拆分每一段数据,将它们转换为二进制整数,然后将它们放入二进制数组中。之后,您可以使用数组的tofile()
方法写入文件。
from array import *
bin_array = array('B')
bin_array.append(int('011',2))
bin_array.append(int('010',2))
bin_array.append(int('110',2))
f = file('binary.mydata','wb')
bin_array.tofile(f)
f.close()
答案 2 :(得分:4)
我希望将1和0的模式写入文件。
如果您的意思是想要将字符串中的比特流写入文件,那么您需要这样的内容......
from cStringIO import StringIO
s = "001011010110000010010"
sio = StringIO(s)
f = open('outfile', 'wb')
while 1:
# Grab the next 8 bits
b = sio.read(8)
# Bail if we hit EOF
if not b:
break
# If we got fewer than 8 bits, pad with zeroes on the right
if len(b) < 8:
b = b + '0' * (8 - len(b))
# Convert to int
i = int(b, 2)
# Convert to char
c = chr(i)
# Write
f.write(c)
f.close()
... xxd -b outfile
显示......
0000000: 00101101 01100000 10010000 -`.
答案 3 :(得分:1)
简要示例:
my_number = 1234
with open('myfile', 'wb') as file_handle:
file_handle.write(struct.pack('i', my_number))
...
with open('myfile', 'rb') as file_handle:
my_number_back = struct.unpack('i', file_handle.read())[0]
答案 4 :(得分:0)
每次追加array.array
3位仍会为每个值产生8位。将011
,010
和110
附加到数组并写入磁盘将生成以下输出:00000011 00000010 00000110
。注意那里的所有填充零。
相反,你想要&#34; compact&#34;二进制三元组转换为字节以节省空间。给出问题中的示例字符串,您可以将其转换为整数列表(一次8位),然后直接将其写入文件。这将使用每个值仅3位而不是8来将所有位打包在一起。
original_string = '001011010110000010010'
# first split into 8-bit chunks
bit_strings = [original_string[i:i + 8] for i in range(0, len(original_string), 8)]
# then convert to integers
byte_list = [int(b, 2) for b in bit_strings]
with open('byte.dat', 'wb') as f:
f.write(bytearray(byte_list)) # convert to bytearray before writing
byte.dat的内容:
2D 60 12
00101101 01100000 00010010
二进制(3位):001 011 010 110 000 000 010 010
^^ ^ (Note extra bits)
请注意,此方法将填充最后一个值,使其与8位边界对齐,并且填充将转到最高有效位(上述输出中最后一个字节的左侧)。因此,您需要小心,并可能在原始字符串的末尾添加零,以使字符串长度为8的倍数。