Закрытие ZipOutputStream - PullRequest
       2

Закрытие ZipOutputStream

11 голосов
/ 13 января 2011

Я немного растерялся. Я знаю, что пустой почтовый индекс не является законным. Но как насчет этого образца фрагмента:

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)

В этой ситуации, что было бы самым чистым способом закрыть поток?

Спасибо ...

Ответы [ 3 ]

7 голосов
/ 13 января 2011

Вы должны закрыть 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 находится в Джакарта Commons IO . Использование этого означает, что вам не нужно иметь дело с возможным, но редко полезным IOException, который может быть брошен close().

3 голосов
/ 17 мая 2012

Вместо того, чтобы закрывать поток только при добавлении чего-либо, я выполнил проверку состояния, чтобы увидеть, есть ли что-нибудь, что нужно сжать, перед запуском почтового индекса. Это помогло мне упростить процесс, и я думаю, что в целом его можно использовать для решения проблемы «ZIP-файл должен иметь хотя бы одну запись». Правда, закрытие zos может вызвать другие исключения, но это редко.

Я думаю, что это проблема с Java, которая не обрабатывает случай, когда нет файлов для архивирования.

т.е:

int itemsToAdd=0;
//....

if ( itemsToAdd > 0 ) {

    ZipOutputStream zos = new ZipOutputStream(file);
    try {
        //add files to zip
    }
    finally {
        zos.close();
    }
}
3 голосов
/ 13 января 2011

Вы должны отслеживать, добавили ли вы 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.

...