如何缓存文件句柄?

时间:2013-02-12 21:47:34

标签: java caching clojure

我有一个想要保持打开许多文件的应用程序:它会定期收到客户端请求 说“将一些数据添加到文件X”,这个文件已经打开,文件是理想的 标题部分已经解析,因此写入速度很快。但是,保持打开这么多文件是 对操作系统不太好,如果我们的数据存储需求增长,可能会变得不可能。

所以我想要一个“给我这个文件句柄,如果它没有被缓存则打开”功能,以及一些过程 用于自动关闭尚未写入的文件,比如五分钟。为了 缓存文件句柄的特定情况,写入短喷,这可能就足够了, 但这似乎是一个足够普遍的问题,应该有“给我一个名为X的对象, 如果可能的话,从缓存“和”我现在已完成对象X,因此使其有资格驱逐五 从现在起几分钟“。

core.cache看起来可能适合这种情况 目的,但documentation非常缺乏和 source 没有提供有关如何使用它的特定线索。它的TTLCache看起来很有前途,但同样存在 不清楚如何使用它依赖垃圾收集来驱逐物品,所以我不能干净地关闭一个 资源,当我准备好到期。

当然,我可以自己动手,但是有一些棘手的问题,我相信我会得到一些 事情巧妙地错了,所以我希望那里有人可以指点我这个的实现 功能。我的代码是clojure,但是当然使用java库会很好 这就是可以找到最佳实施的地方。

3 个答案:

答案 0 :(得分:5)

查看Guava's cache implementation

  • 如果句柄被缓存,您可以为Callable方法提供CacheLoader(或get),返回它,否则打​​开,缓存并返回它” 语义
  • 您可以配置定时驱逐,例如expireAfterAccess
  • 您可以注册RemovalListener以关闭删除时的句柄

使用CacheLoader

稍微修改链接的Guava页面中的代码示例
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
    }
  };

*免责声明* 我没有以这种方式使用缓存,请确保您明智地进行测试。

答案 1 :(得分:1)

答案 2 :(得分:0)

操作系统有一些限制:Is there a limit on number of open files in Windows

SortedMap< Date, File > cache = new TreeMap<>();
cache.put( new Date(), file );
Timer timer = new Timer( true );
timer.scheduleAtFixedRate( task, 60*1000L, 60*1000L );

要清除缓存:首先删除它的年龄&gt; 5分钟,重复直到第一年龄> 5分钟。