2011-01-13 13 views
11

Estoy un poco confundido. Sé que un zip vacío no es legal. Pero ¿qué pasa con esta muestra fragmento:Cierre de ZipOutputStream

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

Si no hay entradas zip se habían añadido por alguna razón (posible situación excepcional) a continuación, la siguiente excepción será lanzada en una estrecha intento:

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) 

En esta situación ¿Cuál sería la forma más limpia de cerrar la corriente?

Gracias ...

Respuesta

7

Debe cerrar el FileOutputStream, no el ZipOutputStream, porque el primero es lo que realmente consume los recursos del sistema.

La clase IOUtils se encuentra en Jakarta Commons IO. Usarlo significa que no tiene que lidiar con el IOException posible pero raramente útil que puede arrojarse al close().

+0

Gracias por su ayuda, esta debería ser la verdad :-) –

+0

@lucho - acaba de editar el ejemplo para hacerlo más robusto. – Anon

+6

Esta solución está bien, pero el razonamiento es incorrecto: puede cerrar cualquiera de las transmisiones. Al cerrar una secuencia contenedora como ZipOutputStream también se cerrará FileOutputStream de nivel inferior. –

3

Debe realizar un seguimiento de si se ha añadido cosas la corriente de cremallera y cerrarla sólo cuando se añadieron cosas:

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

de si usted no necesita el recuento sólo tiene que utilizar una boolean bandera.

+0

El archivo zip permanece abierta y cerrada de esa manera ... ¿Cómo cerrarla? –

+0

@lucho agregó un código para cerrar el archivo cuando la secuencia zip está vacía. echar un vistazo. –

3

En lugar de cerrar la transmisión solo cuando se agregan cosas, lo que hice fue una verificación de condición para ver si había algo que comprimir, antes de ejecutar el código postal. Esto me ayudó a simplificar el proceso y creo que se puede usar en general para manejar el problema de que "el archivo ZIP debe tener al menos una entrada". Es cierto que cerrar zos puede arrojar otras excepciones, pero eso es raro.

Creo que es un problema con Java, que no maneja el caso cuando no hay archivos para comprimir.

es decir:

int itemsToAdd=0; 
//.... 

if (itemsToAdd > 0) { 

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