Python将长整型以二进制值写入文件
我一直在尝试把一个长整型数字(m39素数)存储为二进制文件。当我试图把这个二进制值写入文件时,它却变成了字符串。
>>> m39 = bin(2**13466917-1)
>>> open('m39', 'wb').write(m39)
madsc13ntist@jaberwock:~/Desktop$ xxd m39 | head
0000000: 3062 3131 3131 3131 3131 3131 3131 3131 0b11111111111111
0000010: 3131 3131 3131 3131 3131 3131 3131 3131 1111111111111111
0000020: 3131 3131 3131 3131 3131 3131 3131 3131 1111111111111111
0000030: 3131 3131 3131 3131 3131 3131 3131 3131 1111111111111111
0000040: 3131 3131 3131 3131 3131 3131 3131 3131 1111111111111111
0000050: 3131 3131 3131 3131 3131 3131 3131 3131 1111111111111111
0000060: 3131 3131 3131 3131 3131 3131 3131 3131 1111111111111111
0000070: 3131 3131 3131 3131 3131 3131 3131 3131 1111111111111111
0000080: 3131 3131 3131 3131 3131 3131 3131 3131 1111111111111111
我感觉这个问题应该有个非常简单的解决办法,但我一直没能成功把m39转换成字节数组或缓冲区来写入。请问我应该使用io还是memoryview等等?
非常感谢任何人提供的帮助。:)
我使用的是Python 2.7.3,尽量想用内置模块。
补充说明:我想把这个值存储为二进制文件,这样在磁盘或内存上占用的空间会小很多。我知道在Python中,bin类型是字符串,但我想写的是\x11\x11\x11\x11而不是\x31\x31\x31\x31
。我的目的是不想打印这个值的字符串表示,而是为了高效地存储,以便后续使用或处理。
2 个回答
2
Python中的pickle
模块非常高效。它的存储方式比原始的二进制值多了8个字节。这在Python 2.X和3.X中都可以使用:
import pickle
m39 = 2**13466917-1
with open('m39.dat','wb') as f:
pickle.dump(m39,f,pickle.HIGHEST_PROTOCOL)
得到的十六进制转储(1,683,373字节):
80 03 8B A5 AF 19 00 FF FF FF ... FF FF FF 1F 2E
要读取数据:
import pickle
with open('m39.dat','rb') as f:
m39 = pickle.load(f)
Python 3还提供了to_bytes
和from_bytes
这两个方法来处理整数,不过这需要多一点工作,因为你需要先计算整数的字节长度。
import math
m39 = 2**13466917-1
s = m39.to_bytes(math.ceil(m39.bit_length()/8),'little')
with open('m39.dat','wb') as f:
f.write(s)
得到的十六进制转储(1,683,365字节):
FF FF FF FF FF FF FF FF FF FF ... FF FF FF FF 1F
要读取数据:
with open('m39.dat','rb') as f:
data = f.read()
m39 = int.from_bytes(data,'little')
显然,这里有一个规律,直接存储质数的指数会更有效率。