Закрытие ZipOutputStream
Я немного смущен. Я знаю, что пустой почтовый индекс не является законным. Но как насчет этого фрагмента образца:
ZipOutputStream zos = null;
try
{
zos = new ZipOutputStream(new FileOutputStream("..."));
//
//..
//
}
finally
{
zos.close();
}
Если по какой-то причине не было добавлено записей zip (возможно, исключительная ситуация), то при попытке закрыть будет сделано следующее исключение:
Exception in thread "main" java.util.zip.ZipException: ZIP file must have at least one entry
at java.util.zip.ZipOutputStream.finish(ZipOutputStream.java:304)
at java.util.zip.DeflaterOutputStream.close(DeflaterOutputStream.java:146)
at java.util.zip.ZipOutputStream.close(ZipOutputStream.java:321)
В этой ситуации будет самый чистый способ закрыть поток?
Спасибо...
Ответы
Ответ 1
Вы должны закрыть FileOutputStream
, а не ZipOutputStream
, потому что первое - это то, что фактически потребляет системные ресурсы.
File zipFile = new File("/tmp/example.zip");
FileOutputStream fos = null;
try
{
fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
// ...
zos.close();
}
catch (IOException ex)
{
// log/report exception, then delete the invalid file
IOUtils.closeQuietly(fos);
zipFile.delete();
}
finally
{
IOUtils.closeQuietly(fos);
}
Класс IOUtils
находится в Jakarta Commons IO. Использование этого означает, что вам не нужно иметь дело с возможным, но редко полезным IOException
, которое может быть выбрано close()
.
Ответ 2
Вы должны отслеживать, добавили ли вы материал zip-потока и закрыли его только тогда, когда все было добавлено:
ZipOutputStream zos = null;
OutputStream file = new FileOutputStream("...")
int itemsAdded=0;
try
{
zos = new ZipOutputStream(file);
//
//..
// itemsAdded++;
}
finally
{
if ( itemsAdded > 0 ) {
zos.close();
} else {
file.close();
}
}
если вам не нужен счет, используйте флаг boolean
.
Ответ 3
Вместо того, чтобы закрывать поток только при добавлении вещей, то, что я сделал, является проверкой состояния, чтобы увидеть, есть ли что-нибудь для zip, перед запуском почтового индекса. Это помогло мне упростить этот процесс, и я думаю, что он может использоваться в целом для обработки проблемы "ZIP файл должен иметь хотя бы одну запись". Правда, что закрытие zos
может вызывать другие исключения, но это редко.
Я думаю, что это проблема с Java, которая не обрабатывает случай, когда нет файлов для zip.
то есть:
int itemsToAdd=0;
//....
if ( itemsToAdd > 0 ) {
ZipOutputStream zos = new ZipOutputStream(file);
try {
//add files to zip
}
finally {
zos.close();
}
}