【问题标题】:Seek on Pickled Data寻找腌制数据
【发布时间】:2019-04-23 11:15:20
【问题描述】:

请问是否可以在 Python 中跳转到腌制文件中的特定记录?

例如:

import pickle

with open ('BinaryFile.dat', mode='wb') as MyFile:
    pickle.dump('Item1', MyFile)
    pickle.dump('Item2', MyFile)
    pickle.dump('Item3', MyFile)
    pickle.dump('Item4', MyFile)
    pickle.dump('Item5', MyFile)

with open('BinaryFile.dat', mode='rb') as MyReadFile:
    MyReadFile.seek(3)
    print(pickle.load(MyReadFile))

_pickle.UnpicklingError: invalid load key, '\x05'.

寻求甚至对挑选的数据起作用吗?我需要多次致电pickle.load(MyReadFile) 吗?

【问题讨论】:

    标签: python pickle seek


    【解决方案1】:

    Pickle 记录可以连接到一个文件中,所以是的,您可以多次 pickle.load(f),但文件本身的索引方式无法让您查找给定记录。

    您的f.seek(3) 正在做的是寻找文件中的第三个字节,它位于pickle 记录的中间,因此是不可腌制的。

    如果您需要随机访问,您可能需要查看built-in shelve module,它使用数据库文件模块在pickle 之上构建了一个类似字典的界面。

    (另一种简单的方法是简单地拥有一个充满泡菜文件的目录。)

    【讨论】:

    • 如果我想在文件中向后移动怎么办?有没有办法pickle.unload(f)
    • 不,但您可以使用f.tell() 找出每个.load() 之后您在文件中的位置,跟踪它们,然后f.seek() 回到您想要的位置。
    • 谢谢。所以我可以使用 seek,但前提是它指向记录的开头?
    【解决方案2】:

    您可以在调用pickle.dump() 之前使用文件tell() 方法显式保存每个项目的起始位置,然后使用该信息在pickle.load() 之前重新定位文件流。

    这就是我的意思:

    import pickle
    
    indices = []
    
    with open ('BinaryFile.dat', mode='wb') as MyFile:
        indices.append(MyFile.tell())
        pickle.dump('Item1', MyFile)
        indices.append(MyFile.tell())
        pickle.dump('Item2', MyFile)
        indices.append(MyFile.tell())
        pickle.dump('Item3', MyFile)
        indices.append(MyFile.tell())
        pickle.dump('Item4', MyFile)
        indices.append(MyFile.tell())
        pickle.dump('Item5', MyFile)
    
    with open('BinaryFile.dat', mode='rb') as MyReadFile:
        MyReadFile.seek(indices[3])
        print(pickle.load(MyReadFile))  # -> Item4
    

    当然,为了真正有用,您还需要将位置数据保存在indices 列表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多