您需要使用 python 的struct.unpack()。您需要准确地知道它们是什么类型,以及它们是如何打包在磁盘上的。 pickle 特定于 Python 的存储格式,对你没有任何用处,除非你将序列化转换为特定于 python 的东西。
我最近回答了一个模糊相似的问题here,它展示了如何在文件中使用mmap(),您可能会发现它比os.read() 更方便
我可能会首先创建一个具有构造函数的类,您可以在其中使用文件指针、mmap 对象和偏移量的某种组合对其进行初始化。
然后__init___() 方法将读取并使用结构的解压缩内容初始化self 的属性。然后添加访问器方法来修改这些属性,然后使用struct.pack 和mmap() 或os.write 将它们全部写回save() 方法
以下是 Python 文档中打包和解包三个整数(2 个 16 位短,后跟一个 32 位长)的示例:
>>> from struct import *
>>> pack('=hhl', 1, 2, 3)
'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('=hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
听起来您的数据可能是可变长度的……这意味着您可能无法就地修改数据。
这是一个使用os.read() 和mmap 的Python2 示例。我用dd if=/dev/zero of=/tmp/three_numbers.dat count=1 bs=1k预先创建了/tmp/three_numbers.dat:
import mmap
import os
import struct
class ThreeNumbers(object):
PACK = '=hhl'
SIZEOF = struct.calcsize(PACK)
def __init__(self, fd, offset):
self._fd = fd
self._offset = offset
self._fd.seek(offset * self.SIZEOF)
self._data = os.read(fd.fileno(), self.SIZEOF)
self.numbers = struct.unpack(self.PACK, self._data)
def save(self):
self._fd.seek(self._offset * self.SIZEOF)
os.write(self._fd.fileno(), struct.pack(self.PACK, *self.numbers))
class ThreeNumbersMMAP(object):
PACK = '=hhl'
SIZEOF = struct.calcsize(PACK)
def __init__(self, mmap, offset):
self._mmap = mmap
self._offset = offset
self._data = mmap[offset * self.SIZEOF:(offset + 1) * self.SIZEOF]
self.numbers = struct.unpack(self.PACK, self._data)
def save(self):
self._mmap[self._offset * self.SIZEOF:(self._offset + 1) * self.SIZEOF] = struct.pack(self.PACK, *self.numbers)
fd = open("/tmp/three_numbers.dat", "rb+")
obj = ThreeNumbers(fd, 0)
print obj.numbers
obj.numbers = (1, 2, 3)
obj.save()
obj = ThreeNumbers(fd, 0)
print obj.numbers
obj.numbers = (0, 0, 0)
obj.save()
mmap = mmap.mmap(fd.fileno(), 0)
obj = ThreeNumbersMMAP(mmap, 0)
print obj.numbers
obj.numbers = (1, 2, 3)
obj.save()
obj = ThreeNumbersMMAP(mmap, 0)
print obj.numbers
obj.numbers = (0, 0, 0)
obj.save()