2011-01-13 13 views
11

Jestem trochę zdezorientowany. Wiem, że pusty zip nie jest legalny. Ale co o tym przykładowym fragmencie:Zamykanie ZipOutputStream

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

Jeśli żadne wpisy na suwak został dodany z jakiegoś powodu (być wyjątkowa sytuacja), wówczas następujący wyjątek zostanie rzucony na ścisłej próbie:

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) 

W tej sytuacji jaki byłby najczystszy sposób zamknięcia strumienia?

Dzięki ...

Odpowiedz

7

Powinieneś zamknąć FileOutputStream, a nie ZipOutputStream, ponieważ pierwsza z nich pochłania zasoby systemowe.

Klasa IOUtils znajduje się w Jakarta Commons IO. Używanie go oznacza, że ​​nie musisz zajmować się możliwym, ale rzadko użytecznym IOException, który można wyrzucić przez close().

+0

Dziękuję za twoją pomoc, to powinna być prawda :-) –

+0

@lucho - właśnie edytowałem przykład, aby był bardziej solidny. – Anon

+6

To rozwiązanie jest w porządku, ale rozumowanie jest niepoprawne: możesz zamknąć dowolny strumień. Zamknięcie strumienia opakowującego, takiego jak ZipOutputStream, spowoduje również zamknięcie niższego poziomu FileOutputStream. –

3

Należy śledzić jeśli dodano rzeczy strumień zip i zamknąć go tylko wtedy, gdy zostały dodane rzeczy:

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(); 
    } 
} 

z jeśli nie musisz liczyć tylko użyć Flaga boolean.

+0

Plik zip pozostaje otwarte i zamknięte w ten sposób ... Jak go zamknąć? –

+0

@lucho dodał kod, aby zamknąć plik, gdy strumień zip jest pusty. Spójrz. –

3

Zamiast zamykania strumienia tylko wtedy, gdy dodawane są pewne rzeczy, wykonałem test warunku, aby sprawdzić, czy było coś do zipowania, przed uruchomieniem kodu pocztowego. Pomogło mi to uprościć proces i myślę, że można go ogólnie wykorzystać do rozwiązania problemu "plik ZIP musi mieć co najmniej jeden wpis". To prawda, że ​​zamknięcie zos może rzucać inne wyjątki, ale zdarza się to rzadko.

Myślę, że to problem z Javą, który nie obsługuje przypadku, gdy nie ma plików do zip.

tj:

int itemsToAdd=0; 
//.... 

if (itemsToAdd > 0) { 

    ZipOutputStream zos = new ZipOutputStream(file); 
    try { 
     //add files to zip 
    } 
    finally { 
     zos.close(); 
    } 
}