2011-01-13 2 views
11

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

ZipOutputStream zos = null; 
try 
{ 
    zos = new ZipOutputStream(new FileOutputStream("...")); 
    // 
    //.. 
    // 
} 
finally 
{ 
    zos.close(); 
} 

Если нет записей почтового индекса не были добавлены по какой-то причине (возможно, исключительная ситуация), то следующее исключение будет выброшено на попытке закрытия:

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) 

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

Благодаря ...

ответ

7

Вы должны закрыть FileOutputStream, а не ZipOutputStream, потому что первое - это то, что фактически потребляет системные ресурсы.

IOUtils класс находится в Jakarta Commons IO. Использование этого означает, что вам не нужно иметь дело с возможным, но редко полезным IOException, который может быть выброшен close().

+0

Спасибо за вашу помощь, это должно быть правдой :-) –

+0

@lucho - только что отредактировал пример, чтобы сделать его более надежным. – Anon

+6

Это решение в порядке, но аргументация неверна: вы можете закрыть любой поток. Закрытие потока оболочки, такого как ZipOutputStream, также закроет файл FileOutputStream более низкого уровня. –

3

Вы должны отслеживать, если вы добавили материал почтового потока и закрыть его только тогда, когда были добавлены вещи:

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 флаг.

+0

Файл почтового индекса остается открытым и заперли таким образом ... Как закрыть? –

+0

@lucho добавил некоторый код, чтобы закрыть файл, когда почтовый поток пуст. взглянуть. –

3

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

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

т.е:

int itemsToAdd=0; 
//.... 

if (itemsToAdd > 0) { 

    ZipOutputStream zos = new ZipOutputStream(file); 
    try { 
     //add files to zip 
    } 
    finally { 
     zos.close(); 
    } 
} 
Смежные вопросы