如何使用try-with-resources传递Java中某些AutoCloseable的所有权?

时间:2018-10-23 15:24:38

标签: java resources try-with-resources autocloseable

我的用例是创建并读取一个ZIP文件,因此我需要首先创建该文件,如果成功,则需要给调用者一个读取文件的机会。一旦发生异常或不再需要该文件,应将其创建为临时文件并自动删除。上下文是一些运行时间较长的Java守护程序,因此仅在关闭JRE时删除文件不是一个好的解决方案,因为在那之前我可能已经积累了很多临时文件,占用了GiB的空间。

以下内容用于创建临时文件,以便将其自动删除,并且我可以进行读写:

Path            path    = Files.createTempFile(prefix, ".zip");
OpenOption[]    options = new OpenOption[] {StandardOpenOption.READ,
                                            StandardOpenOption.WRITE,
                                            StandardOpenOption.DELETE_ON_CLOSE};

return Files.newByteChannel(path, options);

使用以下方法创建ZIP并将其准备好进行读取:

public BufferedInputStream zip() throws IOException
{
    try (   SeekableByteChannel     tmpFile = this.newTmpFile();
            ZipArchiveOutputStream  zip     = new ZipArchiveOutputStream(tmpFile))
    {
        [...]
        zip.finish();
        tmpFile.position(0);

        InputStream         inputStream = Channels.newInputStream(tmpFile);
        BufferedInputStream retVal      = new BufferedInputStream(inputStream);

        return retVal;
    }
}

我想使用try-with-resources来确保在异常情况下该文件已正确关闭,并且因为无论如何总是需要关闭ZipArchiveOutputStream。但是,如果成功,则当然不应关闭和删除基础文件,而应使用try-with-resources将其传递给某个拥有资源及其本身所有权的调用者。我知道我可以使用普通的try-catch-finally来不同地处理成功和异常,但是我认为try-with-resources看起来更干净。

因此,在成功创建ZIP后,有什么方法可以将我的临时文件传递给调用者而不关闭它?也许某些包装对象实现了一定的引用计数,并且仅在达到某个阈值之后才通过close传递调用?

我找不到一个并为此目的实现了自己的实现,但是,如果可能的话,我更喜欢一些通用的方法。使用我目前的方法,我需要为每个托管资源实现一个实现,因为我需要实现委派模式来获得对托管资源close的控制。

谢谢!

0 个答案:

没有答案