好的 - 第一次尝试发布到 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