Мой вариант использования - создание и чтение 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
управляемого ресурса.
Спасибо!