2009-11-16 18 views
5

Llamo a un servicio que devuelve un archivo comprimido. Tengo los datos como InputStream (cortesía de javax.activation.DataHandler.getInputStream();) de la respuesta.¿Cómo obtengo el InputStream de datos descomprimidos de un InputStream de datos GZIPed?

Lo que me gustaría hacer es, sin escribir nada en el disco, obtener un InputStream de los datos descomprimidos en el archivo que está en el archivo. El archivo comprimido en este caso es un documento xml que estoy tratando de eliminar utilizando javax.xml.bind.Unmarshaller que toma un InputStream.

Actualmente estoy tratando de escribir el InputStream a un OutputStream (descomprimir los datos) y luego tendré que volver a escribirlo en un InputStream. Todavía no está funcionando, así que pensé en ver si había un mejor enfoque (ojalá).

Puedo escribir los InputStream inicial en el disco y obtener un archivo gz, y luego leer ese archivo, obtener el archivo comprimido fuera de él e ir de allí pero prefiero mantenerlo todo en la memoria es posible.

Actualización 1: Aquí está mi actual (que no trabaja - obtener un "no en formato GZIP" excepción):

ByteArrayInputStream xmlInput = null; 
    try { 
     InputStream in = dh.getInputStream(); //dh is a javax.activation.DataHandler 
     BufferedInputStream bis = new BufferedInputStream(in); 
     ByteArrayOutputStream bo = new ByteArrayOutputStream(); 
     int bytes_read = 0; 
     byte[] dataBuf = new byte[4096]; 
     while ((bytes_read = bis.read(dataBuf)) != -1) { 
      bo.write(dataBuf, 0, bytes_read); 
     } 
     ByteArrayInputStream bin = new ByteArrayInputStream(bo.toByteArray()); 
     GZIPInputStream gzipInput = new GZIPInputStream(bin); 
     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     dataBuf = new byte[4096];; 
     bytes_read = 0; 
     while ((bytes_read = gzipInput.read(dataBuf)) > 0) { 
      out.write(dataBuf, 0, bytes_read); 
     } 
     xmlInput = new ByteArrayInputStream(out.toByteArray()); 

Si en vez de escribir en un ByteArrayOutputStream escribo a un FileOutputStream la primera vez que obtener un archivo comprimido (que puedo abrir manualmente para obtener el archivo xml) y el servicio (eBay) dice que debe ser un archivo gzip, por lo que no estoy seguro de por qué obtengo el error "No en formato GZIP".

Actualización 2: Probé algo un poco diferente - el mismo error ("No en formato GZIP"). Wow, intenté terminar ese paréntesis con un punto y coma. De todos modos, aquí está mi segundo intento, que todavía no funciona:

ByteArrayInputStream xmlInput = null; 
    try { 
     GZIPInputStream gzipInput = new GZIPInputStream(dh.getInputStream()); 
     ByteArrayOutputStream bo = new ByteArrayOutputStream(); 
     int bytes_read = 0; 
     byte[] dataBuf = new byte[4096]; 
     while ((bytes_read = gzipInput.read(dataBuf)) != -1) { 
      bo.write(dataBuf, 0, bytes_read); 
     } 
     xmlInput = new ByteArrayInputStream(bo.toByteArray()); 
+0

Parece que un gran problema fue que eBay dijo que me estaban dando un gzip pero en realidad era un zip. –

Respuesta

2

El siguiente código debería funcionar. Tenga en cuenta que deberá manejar excepciones de manera adecuada.

OutputStream out = null; 
InputStream in = null; 
try { 
    out = /* some output stream */; 
    in = new java.util.GZIPInputStream(/*some stream*/); 
    byte[] buffer = new byte[4096]; 
    int c = 0; 
    while ((c = in.read(buffer, 0, 4096)) > 0) { 
     out.write(buffer, 0, c); 
    } 
} finally { 
    if (in != null) { 
     in.close(); 
    } 
    if (out != null) { 
     out.close(); 
    } 
} 
0

Eche un vistazo a GZIPInputStream. Here's an example; la clase maneja esto de manera muy transparente, casi no es trabajo de usar.

+1

Simplemente curiosidad: ¿por qué expliticily 1.4.2? ¿Por qué no solo los últimos disponibles aquí? http://java.sun.com/javase/6/docs/api/java/util/zip/GZIPInputStream.html – BalusC

+0

Lo siento, debería haber optado por "Creo que primero está disponible en 1.4.2". Déjame editar ese. :-) –

+0

Estoy buscando en GZIPInputStream en lo que estoy trabajando actualmente aunque recibo una excepción de "No en formato GZIP". No entiendo esto ya que puedo escribir el archivo en el disco y ES un archivo comprimido (gzip según la documentación). Agregaré lo que actualmente (no estoy trabajando) a la pregunta. –

3

Decora el flujo de entrada con un GZIPInputStream.

InputStream decompressed = new GZIPInputStream(compressed);