【问题标题】:Seek into a file full of pickled objects寻找一个充满腌制对象的文件
【发布时间】:2011-04-07 11:19:41
【问题描述】:

我有一个包含腌制对象的巨大文件,让我们假设:

for object in objects:
   pickle.dump(myfile,object)

虽然对象类型相同,但大小不同。
该文件在不同的场合被填满了很长时间,但有时,当转储过程重新启动时,我需要读取最后一个对象。
像这样的:

 myfile.seek(-1000,2)
 while myfile.tell() < mysize:
    objects.append(pickle.load(myfile))

现在,这显然不起作用,因为 -1000 通常不在其中一个对象的开头,并且 pickle 会引发异常等...
虽然我可以尝试 except:pass 并让 pickle 失败,直到它找到可以选择的东西,但我不太喜欢这个想法,我怀疑它确实在某些读取尝试中过度推进了文件,我可能会丢失一些对象。

从头开始读取文件不是一个选项,因为它的大小。

对此有何想法?有没有办法让pickle检查当前文件光标是否指向看起来像对象的东西?

【问题讨论】:

  • 你为什么不用shelve

标签: python file pickle


【解决方案1】:

一种方法是这样做:

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 模块。

【讨论】:

    【解决方案2】:

    在任何地方保存因更新文件而产生的每个文件大小增量的序列

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多