如何追加一个二进制文件?
这个问题和Project Euler的第10题有关:计算低于两百万的所有质数的总和。在我找到正确的算法之前,程序运行得非常慢,所以我决定把找到的质数分批写入一个数据文件。现在我有了正确的主算法,但我想知道如何在数据文件中追加内容。
#Project Euler 10a: list primes below 2,000,000.
import pickle
def numprime(x):
for i in range(2, int(x**0.5)+1):
if x % i == 0:
return False
else:
return True
def growfile(primes, faccess):
file = open('primelist2kk.dat', faccess)
pickle.dump(primes, file)
file.close()
def main(fchunk, faccess):
#File input broken up for memory
for i in range(10):
plist = []
for j in range(1, fchunk, 2):
k = fchunk*i + j
if numprime(k):
plist.append(k)
if i == 0:
plist.pop(0)
plist.insert(0,2)
print()
print(plist)
growfile(plist, faccess)
def viewfile(faccess):
g = open('primelist2kk.dat', faccess)
h = pickle.load(g)
g.close()
print(h)
g.closed
#Supply 1/10 of the prime upper bound
#main(200, 'ab')
viewfile('rb')
我尝试了各种合理的文件访问代码组合,但都没有成功。要么后面的数据块覆盖了第一个,要么根本没有保存。有没有什么好主意?
注意:取消注释main()以创建文件并显示程序输出。注释掉main(),然后取消注释viewfile()以查看文件。
2 个回答
0
你需要使用追加模式,也就是这样。
faccess = 'ab'
顺便提一下,埃拉托斯特尼筛法是一种更快生成质数的方法。
这是筛法的一个例子。
N = range(2000000)
P = []
for i in N:
if i > 1:
P.append(i)
N[::i] = [0]*((len(N)+i-1)//i)
print P
3
你需要用追加模式来更新你的文件(ab
),但这还不够。每次用 pickle.dump
写入的二进制数据块都是独立的。当你用 pickle.load
从打开的文件中读取时,只能得到第一个数据块。你需要用循环不断读取数据,直到没有更多的数据为止。
def viewfile():
with open('primelist2kk.dat', 'rb') as g:
try:
while True: # run until there's an exception
h = pickle.load(g)
print(h)
except EOFError: # this will be raised by load() when there's no more data
pass
如果你不想让每个数据块单独打印出来,你可以把它们放在一个列表里一起处理。