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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16887493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:56:02  来源:igfitidea点击:

Write a binary integer or string to a file in python

pythonfilefile-iobinary

提问by KFox

I have a string (it could be an integer too) in Python and I want to write it to a file. It contains only ones and zeros I want that pattern of ones and zeros to be written to a file. I want to write the binary directly because I need to store a lot of data, but only certain values. I see no need to take up the space of using eight bit per value when I only need three.

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

For instance. Let's say I were to write the binary string "01100010"to a file. If I opened it in a text editor it would say b(01100010 is the ascii code for b). Do not be confused though. I do not want to write ascii codes, the example was just to indicate that I want to directly write bytes to the file.

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



Clarification:

澄清:

My string looks something like this:

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

binary_string = "001011010110000010010"

It is not made of of the binary codes for numbers or characters. It contains data relative only to my program.

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

采纳答案by KFox

Alright, after quite a bit more searching, I found an answer. I believe that the rest of you simply didn't understand (which was probably my fault, as I had to edit twice to make it clear). I found it here.

好吧,经过相当多的搜索,我找到了答案。我相信你们其他人根本不明白(这可能是我的错,因为我不得不编辑两次才能说清楚)。我在这里找到

The answer was to split up each piece of data, convert them into a binary integer then put them in a binary array. After that, you can use the array's tofile()method to write to a file.

答案是将每条数据拆分,将它们转换为二进制整数,然后将它们放入二进制数组中。之后,您可以使用数组的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()

回答by Ryan Haining

To write out a string you can use the file's .writemethod. To write an integer, you will need to use the structmodule

要写出一个字符串,您可以使用文件的.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')

However, the representation of int and string are different, you may with to use the binfunction instead to turn it into a string of 0s and 1s

但是,int 和 string 的表示不同,你可以用bin函数代替,把它变成一个 0 和 1 的字符串

>>> bin(7)
'0b111'
>>> bin(7)[2:] #cut off the 0b
'111'

but maybe the best way to handle all these ints is to decide on a fixed width for the binary strings in the file and convert them like so:

但也许处理所有这些ints的最佳方法是确定文件中二进制字符串的固定宽度,然后像这样转换它们:

>>> x = 7
>>> '{0:032b}'.format(x) #32 character wide binary number with '0' as filler
'00000000000000000000000000000111'

回答by Aya

I want that pattern of ones and zeros to be written to a file.

我希望将 1 和 0 的模式写入文件。

If you mean you want to write a bitstream from a string to a file, you'll need something like this...

如果您的意思是要将比特流从字符串写入文件,则需要这样的东西...

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

...for which xxd -b outfileshows...

...对于哪个xxd -b outfile节目...

0000000: 00101101 01100000 10010000                             -`.

回答by jdk1.0

Appending to an array.array3 bits at a time will still produce 8 bits for every value. Appending 011, 010, and 110to an array and writing to disk will produce the following output: 00000011 00000010 00000110. Note all the padded zeros in there.

一次附加array.array3 位仍然会为每个值产生 8 位。将011010和附加110到数组并写入磁盘将产生以下输出:00000011 00000010 00000110. 注意那里所有的填充零。

It seems like, instead, you want to "compact" binary triplets into bytes to save space. Given the example string in your question, you can convert it to a list of integers (8 bits at a time) and then write it to a file directly. This will pack all the bits together using only 3 bits per value rather than 8.

相反,您似乎希望将二进制三元组“压缩”为字节以节省空间。给定问题中的示例字符串,您可以将其转换为整数列表(一次 8 位),然后直接将其写入文件。这会将所有位打包在一起,每个值仅使用 3 位而不是 8 位。

Python 3.4 example

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

Contents of byte.dat:

byte.dat 的内容:

  • hex: 2D 60 12
  • binary (by 8 bits): 00101101 01100000 00010010
  • binary (by 3 bits): 001 011 010 110 000 000 010 010

                                        ^^ ^ (Note extra bits)
    

    Note that this method will pad the last values so that it aligns to an 8-bit boundary, and the padding goes to the most significant bits (left side of the last byte in the above output). So you need to be careful, and possibly add zeros to the end of your original string to make your string length a multiple of 8.

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

                                        ^^ ^ (Note extra bits)
    

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

回答by ThorSummoner

Brief example:

简要示例:

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]