如何在Python中将单个位写入文本文件?

7
假设我有一个数字824,并使用Python将其写入文本文件。在文本文件中,它将占用3个字节的空间。然而,如果我使用位表示,它将具有以下表示形式0000001100111000,这是2个字节(16位)。我想知道如何在Python中将位写入文件,而不是字节。如果我能做到这一点,文件的大小将为2个字节,而不是3个字节。 请提供代码。我正在使用Python 2.6。此外,我不想使用任何不随基本安装一起提供的外部模块。 我尝试了下面的代码,但它给了我12个字节!
```python num = 824 with open('file.txt', 'wb') as f: f.write(str(num)) ```
a =824;
c=bin(a)
handle = open('try1.txt','wb')
handle.write(c)
handle.close()
3个回答

10

你需要的是 struct 模块。从你的例子中可知,824 = 0000001100111000 二进制或 0338 十六进制。这是两个字节 03H 和 38H。 struct.pack 函数可以将 824 转换为这两个字节的字符串,但你还需要决定是小端序(先写入 38H)还是大端序(先写入 03H)。

示例

>>> import struct
>>> struct.pack('>H',824) # big-endian
'\x038'
>>> struct.pack('<H',824) # little-endian
'8\x03'
>>> struct.pack('H',824)  # Use system default
'8\x03'

struct返回一个两个字节的字符串。 '\x##' 表示(一个十六进制值为##的字节)。 '8' 是 ASCII 中的 '8'(值为38H)。 Python 字节串对可打印字符使用 ASCII 编码,对不可打印字符使用 \x## 编码。

下面是一个将二进制数据写入和读取出来的示例代码。在写入和读取二进制文件时,应始终指定大小端序,以防在使用不同大小端默认设置的系统上进行读取:

import struct

a = 824
bin_data = struct.pack('<H',824)
print 'bin_data length:',len(bin_data)

with open('data.bin','wb') as f:
    f.write(bin_data)

with open('data.bin','rb') as f:
   bin_data = f.read()
   print 'Value from file:',struct.unpack('<H',bin_data)[0]

print 'bin_data representation:',repr(bin_data)
for i,c in enumerate(bin_data):
    print 'Byte {0} as binary: {1:08b}'.format(i,ord(c))

输出

bin_data length: 2
Value from file: 824
bin_data representation: '8\x03'
Byte 0 as binary: 00111000
Byte 1 as binary: 00000011

1
但是,例如数字5,我可以使用1个字节来表示它。在这种情况下,我不想使用2个字节。有什么解决方法吗?我想使用最少的字节数。 - Programmer
1
阅读结构文档。如果值适合一个字节,请使用B而不是H。 - Mark Tolonen

5

来看一下struct

>>> struct.pack("h", 824)
'8\x03'

请问您能否详细说明上述内容?可以提供一些代码,演示如何将824转换为二进制格式,并以“按位运算”的方式将其写入文件。 - Programmer
也就是说,在文件中它应该占用2个字节,而不是3个。 - Programmer

2

我认为你想要的是以二进制模式打开文件:

open("file.bla", "wb")

然而,这样会将一个整数写入文件,其大小可能为4个字节。我不知道Python是否有2个字节的整数类型。但是你可以通过在一个32位数字中编码2个16位数字来避免这个问题:

a = 824
b = 1234
c = (a << 16) + b

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