2010-11-12 11 views
6

tengo que cargar con esta prueba junit:¿Por qué ZipInputStream no puede leer la salida de ZipOutputStream?

public void test() throws Exception { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    ZipOutputStream zipOut = new ZipOutputStream(out); 
    zipOut.putNextEntry(new ZipEntry("file")); 
    zipOut.write((new byte[] { 0x01, 0x02, 0x03 })); 
    zipOut.closeEntry(); 
    zipOut.close(); 

    ZipInputStream zipIn = new ZipInputStream(new ByteArrayInputStream(out.toByteArray())); 
    ZipEntry entry = zipIn.getNextEntry(); 
    assertNotNull(entry); 
    assertEquals("file", entry.getName()); 
    assertEquals(3, entry.getSize()); 
} 

Estoy escribiendo un archivo con el "archivo" nombre y un contenido de tres bytes a un ZipOutputStream. Luego trato de leer los datos creados con un ZipInputStream, pero la última afirmación falla, porque entry.getSize() es -1 y no 3, como se esperaba.

¿Qué estoy haciendo mal aquí? ¿Qué debo cambiar para restaurar el contenido de "archivo"? Creo que primero tengo que saber la longitud para poder leer los datos de la transmisión.

+0

Has probado tu código, de hecho, no funciona. Estoy desconcertado. Investigando ... –

+0

Lo tengo. Responda abajo. –

Respuesta

4

De hecho tienes que leer el contenido de la entrada, entonces entry.getSize() devolverá el tamaño correcto .

Para leer utilización entrada:

byte[] buf = new byte[1024]; 
    int len; 
    while ((len = zipIn.read(buf)) > 0) { 
     // use data; 
    } 
+0

Oh, eso es bueno. Me perdí de ver los campos de información de zipEntry después de leer los datos ... ¡Gracias por esta pista! – tangens

+2

El caso es que hay una entrada LOC que precede a una entrada zipEntry y una entrada EXT después de una entrada zip. Ambos tienen un campo de tamaño. ZipOutputStream siempre escribe 0 en LOC.size, mientras que otros archivadores escriben el tamaño en LOC así como en EXT. Me pregunto cuántos problemas esto puede causar, y cómo hacer que ZipOutputStream escriba el tamaño en el LOC. – rustyx

1

Encontré la respuesta por mi cuenta: entry no contiene el tamaño correcto, pero con cada zipIn.getNextEntry() recibe una nueva corriente para leer el contenido de su entrada. Simplemente lea la transmisión hasta el final y tenga los datos de su entrada.

En mi prueba junit la última línea podría tener este aspecto:

byte[] restoredContent = new byte[ 10 ]; 
assertEquals(3, zipIn.read(restoredContent)); 

Ahora todo funciona bien.

1

Lea API doc para ZipEntry. Dice "si se sabe". Usted puede leer el contenido utilizando la siguiente (sólo se imprime el tamaño de la ZipEntry, cambiarlo procesar datos de manera apropiada):

ZipEntry entry = zipIn.getNextEntry(); 
int BUFSIZE = 1024; 
byte [] buffer = new byte[BUFSIZE]; 
int read = 0; 
int total = 0; 
while((read = zipIn.read(buffer, 0, BUFSIZE)) >0) { 
    total += read; 
    // what do you want to do with the data read? Do it here 
} 
System.err.println("Total: " + total); 
-1

El mismo problema aquí!

ZipInputStream no puede leer la salida de ZipOutputStream;

nueva ZipFile (archivo) falla con un error

ninguna explicación posible!

¡El programa del visor de archivos abre el archivo zip muy bien!

SOLUCIÓN: Uh ... no era un archivo zip después de todo ... era un alquitrán llamado 'folder.zip'. El visor de archivos fue lo suficientemente inteligente ...

Para quienes tienen este problema: ¡¡¡Doble comprobación !!!

+2

Lo siento, ¿pero de qué estás hablando? ¿Usted escribió un TAR con un ZipOutputStream? – rustyx

0

Recientemente tuve un problema similar al leer un zip de bytes creados con ZipOutputStream.

El siguiente fragmento de código llevó a java.lang.NegativeArraySizeException.

zipEntry = zipInputStream.getNextEntry(); 
byte[] bytes = new byte[(int) zipEntry.getSize()]; 

Una solución rápida que era utilizar Apache Commons-io IOUtils para leer los todos los bytes de entrada actual.

zipEntry = zipInputStream.getNextEntry(); 
byte[] bytes = org.apache.commons.io.IOUtils.toByteArray(zipInputStream); 

Espero que esto sea útil para alguien.

Cuestiones relacionadas