もっと良い答えがあるかもしれません… しかし、私がこの問題に直面したとき、私はすでに別々の部分にアクセスしたいファイルを持っていたので、この問題を簡単に解決することができました。
たとえば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
ます。ただし、必要に応じて、 を構築する前に明示的に and を構築seek
しread
たり、構築した後に、または で同じ呼び出しを行うこともできます。これは、 and に影響を与えることなく機能します。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
numpy.memmap
numpy.array
numpy
numpy.memmap
mmap