Как передать владение некоторым AutoCloseable в Java, используя try-with-resources? - PullRequest
0 голосов
/ 23 октября 2018

Мой вариант использования - создание и чтение ZIP-файла, поэтому мне нужно сначала создать файл, и, если это удастся, мне нужно дать своему вызывающему абоненту возможность прочитать его.Файл должен быть создан как временный с автоматическим удалением, как только возникает исключение или файл больше не нужен.Контекст - это какой-то давно работающий Java-демон, поэтому удаление файла при закрытии только JRE не является хорошим решением, потому что до этого времени я мог накопить много временных файлов, уже занимающих ГиБ места.

Следующееиспользуется для создания временного файла, чтобы он автоматически удалялся, и я могу писать и читать:

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 управляемого ресурса.

Спасибо!

...