python从文件

时间:2016-06-16 17:42:10

标签: python-2.7 file

我是python的新手所以我不知道一些基本的东西。我有一个二进制文件,其中包含一个对象数组。存储的对象是传统的C结构。我想在python中重新创建该结构,并在其对象列表中读取文件内容,对数据进行一些修改并将其存储回来。我遇到麻烦的部分是阅读文件内容。我已经阅读了一些关于阅读文件的类似问题,但他们没有回答我的问题。我尝试用__slot__定义类和定义类成员  并使用pickle读取数据,但它并没有完全奏效。另外,数据成员之一实际上是包含不同结构的对象的数组可能是相关的。阅读此文件的最佳方法是什么?

1 个答案:

答案 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()