我是python的新手所以我不知道一些基本的东西。我有一个二进制文件,其中包含一个对象数组。存储的对象是传统的C结构。我想在python中重新创建该结构,并在其对象列表中读取文件内容,对数据进行一些修改并将其存储回来。我遇到麻烦的部分是阅读文件内容。我已经阅读了一些关于阅读文件的类似问题,但他们没有回答我的问题。我尝试用__slot__
定义类和定义类成员
并使用pickle
读取数据,但它并没有完全奏效。另外,数据成员之一实际上是包含不同结构的对象的数组可能是相关的。阅读此文件的最佳方法是什么?
答案 0 :(得分:0)
您需要使用python' struct.unpack()
。您需要确切地知道它们是什么类型,以及它们如何打包在磁盘上。 pickle
特定于Python的存储格式,除非您将序列化转换为特定于python的内容,否则对您没有任何用处。
我最近回答了一个模糊的问题here,该问题展示了如何在文件中使用mmap()
,您可能会发现os.read()
我可能首先创建一个具有构造函数的类,使用文件指针,mmap
对象和偏移量的某种组合来初始化它。
然后__init___()
方法将读取并使用结构的解压缩内容初始化self
的属性。然后添加访问者方法来修改这些属性,然后使用save()
方法使用struct.pack
mmap()
或os.write
以下是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示例。我使用/tmp/three_numbers.dat
预先创建了dd if=/dev/zero of=/tmp/three_numbers.dat count=1 bs=1k
:
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()