Python将长整型以二进制值写入文件

1 投票
2 回答
4136 浏览
提问于 2025-04-17 20:09

我一直在尝试把一个长整型数字(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_bytesfrom_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')

显然,这里有一个规律,直接存储质数的指数会更有效率。

2

你应该根据数据的结构来选择使用 struct 模块或者 array 模块。如果你的数据是一组相同类型的值,使用 array 会更简单、更快。

撰写回答