我正在使用JENA创建一个三重存储(TDB功能),其代码如下:
public void createTDBFromOWL() {
Dataset dataset = TDBFactory.createDataset(newTripleStoreLocation);
dataset.begin(ReadWrite.WRITE);
try {
//getting the model inside the transaction
Model model = dataset.getDefaultModel();
FileManager fileManager=FileManager.get();
Model holder=fileManager.readModel(model, newOWLFileLocation);
//committing dataset
dataset.commit();
model.close();
holder.close();
} finally {
dataset.end();
dataset.close();
}
}
创建三重存储后,创建的文件被我的应用程序服务器(Glassfish)锁定,在手动停止Glassfish并释放锁定之前我无法删除它们。如上面的代码所示,我认为我正在关闭所有内容,所以我不明白为什么在文件上保持锁定。
答案 0 :(得分:3)
当您致电Dataset#close()
时,呼叫基础的implementation代表
DatasetGraphBase#close()
,然后最终委托给DatasetGraphTDB#_close()
。
这会调用TripleTable#close()
和QuadTable#close()
。这两个调用(几个)NodeTupleTable#close()
。继续间接,这会调用NodeTable#close()
和TupleTable#close()
。前者是一个接口,因此我们需要对您的实现中运行的类进行适当的猜测。后者遍历TupleIndex
个对象的集合,并在每个对象上调用close()
。 TupleIndex
也是一个界面。
来自TupleIndex
的后代只有一个有意义的层次结构会产生可以锁定文件的内容,从而导致我们TupleIndexRecord#close()
。然后,我们可以一直关注RangeIndex
BPlusTree
的特定实施,直到我们看到MappedByteBuffer
的实际所有权
最终,在阅读BlockAccessMapped#close()
的实现时,整个层面似乎正在关闭事物,直到最后的类,但this longstanding bug可能是罪魁祸首。来自文档:
一旦文件被映射,该文件就会有多个操作 在映射被释放之前失败(例如删除,截断为a 大小小于映射区域)。但是程序员无法控制 准确地说,取消映射的时间 - 通常 它取决于最终化处理或PhantomReference 队列中。
所以你有它。尽管Jena做了最大的努力,但还是无法控制何时该文件将在Java中取消映射。这最终是java中内存映射文件IO的权衡。