13

多くのファイルを開いたままにしたいアプリケーションがあります。定期的に「ファイル X にデータを追加する」というクライアント要求を受け取ります。そのファイルを既に開いていて、ファイルのヘッダー セクションが既に解析されていることが理想的です。この書き込みは高速です。ただし、これほど多くのファイルを開いたままにしておくことは、オペレーティング システムにとってあまり好ましくなく、データ ストレージのニーズが増大すると不可能になる可能性があります。

そこで、「このファイル ハンドルを渡して、キャッシュされていない場合は開く」機能と、たとえば 5 分間書き込まれていないファイルを自動的に閉じるプロセスが必要です。短いスパートで書き込まれるファイル ハンドルをキャッシュする特定のケースでは、おそらくこれで十分ですが、これは「可能であればキャッシュから X という名前のオブジェクトを提供してください」や「これでオブジェクト X の処理は完了したので、5 分後に削除できるようにしてください。」

core.cacheはこの目的に適しているように見えますが、ドキュメントが非常に不足しており、 ソース には使用方法に関する特定の手がかりがありません。その TTLCache は有望に見えますが、それを使用する方法が不明であるだけでなく、ガベージ コレクションに依存してアイテムを削除するため、有効期限が切れる準備が整ったときにリソースをきれいに閉じることができません。

もちろん、自分で作成することもできますが、いくつかのトリッキーなスポットがあり、微妙に間違っていると確信しているので、誰かがこの機能の実装を教えてくれることを願っています. 私のコードは clojure で書かれていますが、もちろん、最適な実装が見つかるのであれば、Java ライブラリを使用してもまったく問題ありません。

4

2 に答える 2

6

Guavaのキャッシュ実装を確認してください。

  • 「ハンドルがキャッシュされている場合はそれを返し、そうでない場合は開いてキャッシュして返す」セマンティクスのメソッドにCallable(またはCacheLoader)を指定できます。get
  • ExpireAfterAccessなどの時限エビクションを構成できます
  • RemovalListenerを登録して、削除時にハンドルを閉じることができます

リンクされたGuavaページのコード例を次のように少し変更しますCacheLoader

LoadingCache<Key, Handle> graphs = CacheBuilder.newBuilder()
   .maximumSize(100) // sensible value for open handles?
   .expireAfterAccess(5, TimeUnit.MINUTES)
   .removalListener(removalListener)
   .build(
       new CacheLoader<Key, Handle>() {
         public Handle load(Key key) throws AnyException {
           return openHandle(key);
         }
       });

RemovalListener<Key, Handle> removalListener = 
  new RemovalListener<Key, Handle>() {
    public void onRemoval(RemovalNotification<Key, Handle> removal) {
      Handle h = removal.getValue();
      h.close(); // tear down properly
    }
  };

*免責事項*私はこのように自分でキャッシュを使用していません。これを適切にテストしてください。

于 2013-02-12T22:30:24.600 に答える
1

一部のJavaを気にしない場合は、 http://ehcache.org/およびhttp://ehcache.org/apidocs/net/sf/ehcache/event/CacheEventListener.htmlを参照してください

于 2013-02-12T22:31:38.307 に答える