在python中将二进制整数或字符串写入文件

时间:2013-06-02 21:29:21

标签: python file file-io binary

我在Python中有一个字符串(它也可能是一个整数),我想将它写入文件。它只包含1和0我想要将1和0的模式写入文件。我想直接编写二进制文件,因为我需要存储大量数据,但只需要存储某些值。当我只需要三个时,我认为没有必要占用每个值使用8位的空间。

例如。假设我要将二进制字符串"01100010"写入文件。如果我在文本编辑器中打开它,它会说b(01100010是b的ascii代码)。不要混淆。我不想写ascii代码,这个例子只是为了表明我想直接将字节写入文件。


澄清:

我的字符串看起来像这样:

binary_string = "001011010110000010010"

它不是由数字或字符的二进制代码组成。它包含仅与我的程序有关的数据。

5 个答案:

答案 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位。将011010110附加到数组并写入磁盘将生成以下输出:00000011 00000010 00000110。注意那里的所有填充零。

相反,你想要&#34; compact&#34;二进制三元组转换为字节以节省空间。给出问题中的示例字符串,您可以将其转换为整数列表(一次8位),然后直接将其写入文件。这将使用每个值仅3位而不是8来将所有位打包在一起。

Python 3.4示例

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的内容:

  • hex:2D 60 12
  • 二进制(8位):00101101 01100000 00010010
  • 二进制(3位):001 011 010 110 000 000 010 010

                                        ^^ ^ (Note extra bits)
    

    请注意,此方法将填充最后一个值,使其与8位边界对齐,并且填充将转到最高有效位(上述输出中最后一个字节的左侧)。因此,您需要小心,并可能在原始字符串的末尾添加零,以使字符串长度为8的倍数。