2009-11-16 3 views
5

J'appelle un service qui renvoie un fichier gzippé. J'ai les données en tant que InputStream (courtoisie de javax.activation.DataHandler.getInputStream();) de la réponse.Comment obtenir l'InputStream de données décompressées à partir d'un InputStream de données GZIPed?

Ce que je voudrais faire est, sans rien écrire sur le disque, obtenir un InputStream des données décompressées dans le fichier qui est dans l'archive. Le fichier compressé dans ce cas est un document XML que j'essaie de démasaliser en utilisant javax.xml.bind.Unmarshaller qui prend un InputStream.

J'essaye actuellement d'écrire l'InputStream à un OutputStream (décompressant les données) et alors je devrai l'écrire à un InputStream. Cela ne fonctionne pas encore, alors j'ai pensé que je verrais s'il y avait une meilleure approche (je l'espère).

Je peux écrire l'InputStream initial sur le disque et obtenir un fichier gz, puis lire ce fichier, extraire le fichier compressé et partir de là mais je préfère garder tout en mémoire est possible.

Mise à jour 1: Voici mon actuelle (ne fonctionne pas - obtenir un « pas au format gzip » exception):

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 au lieu d'écrire à un ByteArrayOutputStream j'écris un FileOutputStream la première fois que je obtenir un fichier compressé (que je peux ouvrir manuellement pour obtenir le fichier xml à l'intérieur) et le service (eBay) dit que ce devrait être un fichier gzip donc je ne sais pas pourquoi je reçois une erreur "Pas dans le format GZIP".

Mise à jour 2: J'ai essayé quelque chose d'un peu différent - même erreur ("Pas au format GZIP"). Wow, j'ai juste essayé de terminer cette parenthèse avec un point-virgule. De toute façon, voici ma deuxième tentative, qui ne fonctionne toujours pas:

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

On dirait qu'un gros problème était qu'eBay a dit qu'ils me donnaient un gzip mais c'était en fait un zip. –

Répondre

2

Le code suivant devrait fonctionner. Gardez à l'esprit que vous devrez gérer les exceptions correctement.

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

Jetez un coup d'œil à GZIPInputStream. Here's an example; la classe gère cela de manière très transparente, il n'y a presque pas de travail à faire.

+1

Just curityity: pourquoi expliticily 1.4.2? Pourquoi pas juste le dernier disponible ici? http://java.sun.com/javase/6/docs/api/java/util/zip/GZIPInputStream.html – BalusC

+0

Désolé, j'aurais dû aller avec "Je pense d'abord disponible en 1.4.2". Laissez-moi éditer celui-là. :-) –

+0

Je regarde GZIPInputStream dans ce que je suis en train de travailler même si je reçois une exception "Pas au format GZIP". Je ne comprends pas cela car je peux écrire le fichier sur le disque et c'est un fichier compressé (gzip selon la documentation). Je vais ajouter ce que j'ai actuellement (ne travaille pas) à la question. –

3

Décorez le flux d'entrée avec un GZIPInputStream.

InputStream decompressed = new GZIPInputStream(compressed); 
Questions connexes