1

好的 - 第一次尝试发布到 stackOverflow ......但是我到处搜索,找不到答案,我确定我走错了路,并且觉得这是一个具有普遍适用性的问题,所以就这样吧。

我处理了许多具有许多不同文件类型的不同仪器——但它们通常都使用基于记录的协议来存储数据。例如 - 每个文件包含一个记录序列,每个记录都有一个记录类型标头,其中包括一个同步位,它是什么类型的记录,以及记录的大小。我想构建一个通用类来读取基于记录的文件,我可以为我处理的每种文件类型继承和自定义。文件通常非常大(1GB),所以效率是关键——这也意味着我可能不适合我。

这是我的课。我正在使用文件位置标记在文件中四处跳转,并且担心我正在构建一个非常慢的类 - 考虑到数据的大小和数量,这很重要。错误的轨道?

class RecordBasedFile(object):
    syncpattern = '\xff\xff\x00\x00'
    maxrecsize = 1024*64
    recordIDfromSync = 28
    recordSizefromSync = 4    
    def __init__(self,fileHandle):
        self.fh = fileHandle
        self.recordList = []
        self.sync()

    def sync(self):
        abpos = self.fh.tell()
        chunk = self.fh.read(self.maxrecsize)
        syncbit = chunk.find(self.syncpattern)
        if syncbit >=0:
            self.fh.seek(syncbit+abpos)
            return True
        else:
            return False

    def checkSync(self):
        result = self.fh.read(len(self.syncpattern)) == self.syncpattern
        self.fh.seek(-len(self.syncpattern),1)
        return result        

    def recordID(self):
        return self.getField('<I',self.recordIDfromSync)

    def recordSize(self):
        size = self.getField('<I',self.recordSizefromSync)
        return size       

    def record(self,yieldRecord = True):
        abpos = self.fh.tell()
        rsize,roffset = self.recordSize()
        if yieldRecord:
            self.fh.seek(abpos+roffset)
            output = self.fh.read(rsize)           
        else:
            self.fh.seek(abpos+roffset+rsize)
            output = False
        self.fh.seek(self.endofRecordtoSync,1)
        return output

    def fmtLength(self,Fmt):
        fmt = Fmt.lower()
        return 1 * fmt.count('b') + \
            2*fmt.count('h') + \
            4*(fmt.count('i') + fmt.count('f')) 

    def getField(self,fmt,offset):
        abpos = self.fh.tell()
        self.fh.seek(abpos+offset)
        output = unpack(fmt,self.fh.read(self.fmtLength(fmt)))
        self.fh.seek(abpos)
        return output[0]

    def __iter__(self):
        return self

    def next(self):
        rid = self.recordID()
        record = self.record(yieldRecord = rid in self.recordList)
        if not self.checkSync():
            self.sync
        return rid, record           
4

0 回答 0