我有这个庞大的文件,其中包含了对象,我们假设:
for object in objects:
pickle.dump(myfile,object)
虽然对象的类型相同,但它们的大小不同
该文件在不同的场合会被填充很长时间,但有时,当转储过程重新启动时,我需要读取最后的对象。
像这样:
myfile.seek(-1000,2)
while myfile.tell() < mysize:
objects.append(pickle.load(myfile))
现在,这显然不起作用,因为-1000通常不在其中一个对象的开头,并且pickle会引发异常等...
虽然我可以尝试除了:传递并让pickle失败,直到它找到可选择的东西,我真的不喜欢这个想法,我怀疑它确实在某些读取尝试中推进文件过多而我可能会丢失一些对象。
由于文件的大小,从头开始阅读文件不是一种选择。
这有什么想法吗? pickle有没有办法检查当前文件光标是否指向看起来像对象的东西?
答案 0 :(得分:2)
一种方法是做这样的事情:
import os, pickle, struct
myfile = open('/path/to/my/file', 'w+b')
myfile.write(struct.pack('L', 0)) # write a long of zeroes
index = []
for o in objects:
index.append(myfile.tell())
pickle.dump(o, myfile)
index_loc = myfile.tell()
pickle.dump(index, myfile)
myfile.seek(0, 0, os.SEEK_SET)
myfile.write(struct.pack('L', index_loc))
现在你有一个索引文件:重新打开时,从初始字节读取索引位置,然后搜索到该位置并读取索引。然后,您应该能够以随机访问方式访问文件中的任何对象。 (当然,你可以通过让索引成为文件位置的对象键的字典来概括这一点 - 一种穷人的ZODB)。
或者,当然,您可以使用shelve模块。
答案 1 :(得分:0)
保存因更新文件而导致的每个文件大小增量的序列