0

ネットワーク経由で(主にNFS経由で、場合によってはCIFS経由でも)アクセスする必要のある大きなデータファイルを使用することがよくあります。パフォーマンス上の理由から、これらのファイルをローカルハードドライブにキャッシュして、ネットワークの使用を最小限に抑えることをお勧めします。

したがって、基本的には、ローカルキャッシュを自動的に処理するファイルオブジェクトを探しています。これは次のようなものです。

import CachedFileObject as cfo
cfo.set_local_cache_dir("/tmp")
handle = cfo.open("/nfs/server1/bigdatafile.nc", "r") # copy file to /tmp, open the copy
# do stuff with the filehandle
del handle                                            # delete the local copy

私は本当にこれをファイルを読むためだけに必要とします。ファイルの作成(または書き込み)も取得/実装する簡単な方法があるとしたら、それはボーナスになります。

どんなアイデアでも大歓迎です

4

2 に答える 2

3

ファイルのキャッシュにはオペレーティングシステムを使用します。NFSマウントはキャッシュするように設定でき-o fsc、SMBマウントはデフォルトですでにいくつかのキャッシュがオンになっています。

于 2012-10-17T09:06:11.163 に答える
3

簡単な解決策があります(読み取りアクセスでは完全コピーを開き、書き込みアクセスでは完全コピーを閉じる):

import os
import shutil

from tempfile import mkstemp

class CachedFileObject(object):

    def __init__(self, cache_dir="/tmp"):
        self.cache_dir = cache_dir
        self.local_file = None
        self.local_path = None
        self.remote_path = None
        self.mode = None

    def open(self, path, mode="r", buffering=-1):
        if self.local_file and not self.local_file.closed:
            raise ValueError("Already open")
        fd, self.local_path = mkstemp(dir=self.cache_dir)
        os.close(fd)
        try:
            if "r" in mode and not os.path.exists(path):
                raise ValueError("No such remote file")
            if os.path.exists(path):
                # have remote file
                self._cache_remote(path, self.local_path)
            self.local_file = open(self.local_path, mode=mode, buffering=buffering)
            self.mode = mode
            self.remote_path = path
        except Exception as e:
            os.unlink(self.local_path)
            raise

        return self

    def close(self):
        self.local_file.close()
        try:
            if set("wa+").intersection(set(self.mode)):
                # have writes, sync file back to remote side
                self._sync_remote(self.remote_path, self.local_path)
        finally:
            os.unlink(self.local_path)

    def _cache_remote(self, remote_path, local_path):
        # simple cp
        shutil.copy(remote_path, local_path)

    def _sync_remote(self, remote_path, local_path):
        shutil.copy(local_path, remote_path)

    def __getattr__(self, attr):
        if self.local_file is not None:
            return getattr(self.local_file, attr)
        else:
            raise ValueError("File is not opened")

作成されたオブジェクトは通常のファイルとして動作し、開く/閉じるときにコピー/同期するだけです。

使用法:

f = CachedFileObject(cache_dir="/your/tmp/dir")
f.open("/path/to/remote/file")
# ..your f.read()'s here..
f.close()
于 2012-10-17T09:13:40.567 に答える