2010-07-13 24 views
25

Recibo un ZipInputStream de otra fuente y necesito proporcionar el InputStream de la primera entrada a otra fuente.¿es posible obtener un inputstream de zipentry desde un zipinputstream?

Tenía la esperanza de poder hacer esto sin guardar un archivo temporal en un dispositivo, sin embargo, la única manera que conozco de obtener un InputStream para una entrada individual es a través de ZipFile.getInputStream (entrada) y ya que tengo un ZipInputStream y no un ZipFile, eso no es posible.

Así que la mejor solución que tengo es

  1. Guardar InputStream entrante a un archivo
  2. de archivos de lectura como de eliminación de archivos temporales InputStream
  3. de ZipFile
  4. utilización primera entrada.

Respuesta

31

figuraban:

es completamente posible, la llamada a ZipInputStream.getNextEntry() posiciona el InputStream en el inicio de la entrada y por lo tanto el suministro de los ZipInputStream es el equivalente de suministrar InputStream de un ZipEntry.

ZipInputStream es lo suficientemente inteligente como para manejar el EOF de entrada de la corriente descendente, o al menos eso parece.

p.

+3

¿No entiendo lo que quiere decir con esto? ¿Puedes agregar una muestra de código? – Whitecat

+3

Lo que quiere decir es que ZipInputStream se puede usar tanto para el zip como para el conjunto y para leer cada componente. .getNextEntry() avanza al primer componente, lo lee, hace otro .getNextEntry() y su flujo se restablece al segundo, y así sucesivamente ... Clever, en realidad. – akauppi

11

Además de @pstanton post aquí hay un ejemplo de código. He resuelto el problema usando el siguiente código. Era difícil entender cuál era la respuesta anterior sin un ejemplo.

//If you just want the first file in the zipped InputStream use this code. 
//Otherwise loop through the InputStream using getNextEntry() 
//till you find the file you want. 
private InputStream convertToInputStream(InputStream stream) throws IOException { 
    ZipInputStream zis = new ZipInputStream(stream); 
    zis.getNextEntry(); 
    return zis; 
} 

Usando este código puede devolver un InputStream del archivo que está comprimido.

+0

Y después de que se haya leído el primer componente, uno puede '.getNextEntry()' de nuevo, para leer el segundo. – akauppi

1

El código postal es bastante fácil, pero tuve problemas para volver ZipInputStream como Inputstream. Por algún motivo, algunos de los archivos contenidos en el zip tenían caracteres que se descartaban. La siguiente fue mi solución y hasta ahora ha estado funcionando.

private Map<String, InputStream> getFilesFromZip(final DataHandler dhZ, 
     String operation) throws ServiceFault { 
    Map<String, InputStream> fileEntries = new HashMap<String, InputStream>(); 
    try { 
     ZipInputStream zipIsZ = new ZipInputStream(dhZ.getDataSource() 
     .getInputStream()); 

     try { 
      ZipEntry entry; 
      while ((entry = zipIsZ.getNextEntry()) != null) { 
       if (!entry.isDirectory()) { 
        Path p = Paths.get(entry.toString()); 
        fileEntries.put(p.getFileName().toString(), 
        convertZipInputStreamToInputStream(zipIsZ)); 
       } 
      } 
     } 
     finally { 
      zipIsZ.close(); 
     } 

    } catch (final Exception e) { 
     faultLocal(LOGGER, e, operation); 
    } 

    return fileEntries; 
} 
private InputStream convertZipInputStreamToInputStream(
final ZipInputStream in) throws IOException { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    IOUtils.copy(in, out); 
    InputStream is = new ByteArrayInputStream(out.toByteArray()); 
    return is; 
} 
Cuestiones relacionadas