2

我正在使用 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 并释放它的锁定。如上面的代码所示,我认为我正在关闭所有内容,所以我不明白为什么要在文件上保持锁定。

4

1 回答 1

3

当您调用Dataset#close()时,实现将调用委托给底层 DatasetGraphBase#close(),然后最终委托给DatasetGraphTDB#_close().

这会导致调用TripleTable#close()QuadTable#close()。这两个都调用 (几个) NodeTupleTable#close()。继续间接, this 调用NodeTable#close()and TupleTable#close()。前者是一个接口,因此我们需要正确猜测您的实现中运行的是哪个类。后者遍历TupleIndex对象集合并调用close()它们中的每一个。TupleIndex也是一个接口。

只有一个有意义的后代层次结构TupleIndex会导致可以锁定文件的东西,这导致我们TupleIndexRecord#close(). RangeIndex然后我们可以一直跟踪调用的特定实现,BPlusTree直到我们看到实际所有权MappedByteBuffer

最终,BlockAccessMapped#close()阅读. 从文档中:

一旦一个文件被映射,对该文件的许多操作将失败,直到映射被释放(例如删除、截断到小于映射区域的大小)。然而,程序员无法准确控制取消映射发生的时间——通常它取决于终结处理或 PhantomReference 队列。

所以你有它。尽管 Jena 尽了最大努力,但仍无法控制该文件何时在 Java 中取消映射。这最终成为 java 中内存映射文件 IO 的权衡。

于 2014-04-17T14:30:11.547 回答