2011-01-13 3 views
11

Sono un po 'confuso. So che uno zip vuoto non è legale. Ma che dire di questo campione frammento:Chiusura ZipOutputStream

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

Se erano stati aggiunti nessuna voce di avviamento postale per qualche motivo (possibile situazione di eccezionale) allora la seguente eccezione sarà gettato su una stretta tentativo:

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) 

In questa situazione quale sarebbe il modo più pulito per chiudere il flusso?

Grazie ...

risposta

7

È necessario chiudere lo FileOutputStream, non lo ZipOutputStream, perché il primo è quello che effettivamente consuma le risorse di sistema.

La classe IOUtils si trova in Jakarta Commons IO. Usarlo significa che non si ha a che fare con il possibile, ma raramente utile, IOException che può essere lanciato da close().

+0

Grazie per il tuo aiuto, questa dovrebbe essere la verità :-) –

+0

@lucho - ho appena modificato l'esempio per renderlo più robusto. – Anon

+6

Questa soluzione va bene, ma il ragionamento è errato: è possibile chiudere entrambi i flussi. La chiusura di un flusso di wrapper come ZipOutputStream chiuderà anche FileOutputStream di livello inferiore. –

3

Si dovrebbe tenere traccia se hai aggiunto roba il flusso zip e chiuderlo solo quando sono state aggiunte le cose:

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

di se non è necessario il conteggio basta usare un boolean flag.

+0

Il file zip rimane aperto e bloccato in quel modo ... Come per chiuderla? –

+0

@lucho ha aggiunto del codice per chiudere il file quando lo stream zip è vuoto. guarda. –

3

Invece di chiudere il flusso solo quando vengono aggiunte le cose, ciò che ho fatto è un controllo delle condizioni per vedere se c'era qualcosa da comprimere, prima di eseguire il codice postale. Questo mi ha aiutato a semplificare il processo e penso che possa essere usato in generale per gestire il problema "Il file ZIP deve avere almeno una voce". È vero che la chiusura dello zos potrebbe comportare altre eccezioni, ma ciò è raro.

Penso che sia un problema con Java, che non gestisce il caso quando non ci sono file da comprimere.

cioè:

int itemsToAdd=0; 
//.... 

if (itemsToAdd > 0) { 

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