如何缓存文件句柄?

ama*_*loy 10 java caching clojure

我有一个想要保持打开许多文件的应用程序:它会定期收到客户端请求"将一些数据添加到文件X",并且理想的是已经打开该文件,并且已经解析了文件的标题部分,以便这写得很快.但是,保持打开这么多文件对操作系统来说并不是很好,如果我们的数据存储需求增长,则可能变得不可能.

所以我想要一个"给我这个文件句柄,打开它,如果它没有被缓存"的功能,以及一些自动关闭文件的过程,例如,五分钟没有被写入.对于缓存在短喷射中写入的文件句柄的特定情况,这可能已经足够了,但这似乎是一个足够普遍的问题,应该有"如果可能的话,从缓存中给我一个名为X的对象"和"我现在已经完成了对象X,因此从现在起五分钟后就可以进行驱逐".

core.cache看起来可能适用于此目的,但文档非常缺乏,并且 源代码 没有提供有关如何使用它的特定线索.它的TTLCache看起来很有前景,但是不清楚如何使用它依赖于垃圾收集来驱逐物品,所以当我准备好让它过期时我无法干净地关闭资源.

当然,我可以自己滚动,但是有一些棘手的问题,我确信我会得到一些巧妙的错误,所以我希望有人可以指出我实现这个功能.我的代码是clojure,但是如果可以找到最好的实现,那么使用java库当然会非常好.

Jen*_*ann 5

查看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
    }
  };
Run Code Online (Sandbox Code Playgroud)

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