可能有更好的答案......但是当我遇到这个问题时,我有一个文件,我已经想分别访问不同的部分,这给了我一个简单的解决这个问题的方法。
例如,chunkyfoo.bin
一个文件由一个 6 字节的标头、一个 1024 字节的numpy
数组和另一个 1024 字节的numpy
数组组成。您不能只打开文件并寻找 6 个字节(因为首先要做的numpy.fromfile
是lseek
回到 0)。但是您可以只mmap
使用该文件并使用fromstring
:
with open('chunkyfoo.bin', 'rb') as f:
with closing(mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ)) as m:
a1 = np.fromstring(m[6:1030])
a2 = np.fromstring(m[1030:])
这听起来正是您想要做的。当然,除了在现实生活中,偏移量和长度a1
可能a2
取决于标题,而不是固定的注释。
标头只是m[:6]
,您可以通过显式将其分开、使用struct
模块或您read
在获取数据后执行的任何其他操作来解析它。但是,如果您愿意,您可以在构造 之前、之后或什至对 进行相同的调用seek
,并且它会工作,而不会影响and 。read
f
m
m
a1
a2
我为不同的非numpy
相关项目所做的另一种方法是创建一个包装文件对象,如下所示:
class SeekedFileWrapper(object):
def __init__(self, fileobj):
self.fileobj = fileobj
self.offset = fileobj.tell()
def seek(self, offset, whence=0):
if whence == 0:
offset += self.offset
return self.fileobj.seek(offset, whence)
# ... delegate everything else unchanged
list
我通过在构造时生成属性并在中使用它来“委托其他所有内容不变” __getattr__
,但您可能想要一些不那么老套的东西。numpy
仅依赖于类文件对象的少数方法,我认为它们已正确记录,因此只需明确委派这些方法即可。但我认为该mmap
解决方案在这里更有意义,除非您试图机械地移植一堆基于显式seek
的代码。(您会认为mmap
还可以选择将其保留为 anumpy.memmap
而不是 a numpy.array
,这样可以numpy
更好地控制分页等/反馈。但实际上让 anumpy.memmap
和 anmmap
一起工作非常棘手。)