2009-10-07 29 views
4

J'ai un fichier zip dont le contenu est présenté comme octet [] mais l'objet fichier d'origine n'est pas accessible. Je veux lire le contenu de chacune des entrées. Je suis capable de créer un ZipInputStream à partir d'un ByteArrayInputStream des octets et peut lire les entrées et leurs noms. Cependant, je ne vois pas un moyen facile d'extraire le contenu de chaque entrée.extraction du contenu des entrées ZipFile lors de la lecture de byte [] (Java)

(J'ai regardé Apache Commons mais je ne peux pas y voir un moyen facile non plus).

MISE À JOUR @ code Rich semble résoudre le problème, merci

QUERY pourquoi les deux exemples ont un multiplicateur de 4 * (128/512 et 1024 * 4)?

Répondre

6

Si vous souhaitez traiter des entrées zip imbriquées à partir d'un flux, voir this answer pour des idées. Comme les entrées internes sont listées séquentiellement, elles peuvent être traitées en obtenant la taille de chaque entrée et en lisant autant d'octets dans le flux.

mis à jour avec un exemple qui copie chaque entrée vers la sortie standard:

ZipInputStream is;//obtained earlier 

ZipEntry entry = is.getNextEntry(); 

while(entry != null) { 
    copyStream(is, out, entry); 

    entry = is.getNextEntry(); 
} 
... 

private static void copyStream(InputStream in, OutputStream out, 
     ZipEntry entry) throws IOException { 
    byte[] buffer = new byte[1024 * 4]; 
    long count = 0; 
    int n = 0; 
    long size = entry.getSize(); 
    while (-1 != (n = in.read(buffer)) && count < size) { 
     out.write(buffer, 0, n); 
     count += n; 
    } 
} 
+0

@Rich. J'ai précisé que le fichier zip n'est pas accessible. Je n'ai pas de zips imbriqués. –

+0

J'ai mis à jour ma réponse pour expliquer comment cela peut encore aider. Vous avez un seul flux qui peut lire la taille de chaque entrée du flux –

+0

@Rich. Merci, je vais essayer de lire la taille. –

0

Il utilise en fait le ZipInputStream comme InputStream (mais ne ferment pas à la fin de chaque entrée).

0

Il est un peu difficile de calculer le début du prochain ZipEntry. S'il vous plaît voir cet exemple inclus dans JDK 6,

public static void main(String[] args) { 
    try { 
     ZipInputStream is = new ZipInputStream(System.in); 
     ZipEntry ze; 
     byte[] buf = new byte[128]; 
     int len; 

     while ((ze = is.getNextEntry()) != null) { 
      System.out.println("----------- " + ze); 

      // Determine the number of bytes to skip and skip them. 
      int skip = (int)ze.getSize() - 128; 
      while (skip > 0) { 
       skip -= is.skip(Math.min(skip, 512)); 
      } 

      // Read the remaining bytes and if it's printable, print them. 
      out: while ((len = is.read(buf)) >= 0) { 
       for (int i=0; i<len; i++) { 
        if ((buf[i]&0xFF) >= 0x80) { 
         System.out.println("**** UNPRINTABLE ****"); 

         // This isn't really necessary since getNextEntry() 
         // automatically calls it. 
         is.closeEntry(); 

         // Get the next zip entry. 
         break out; 
        } 
       } 
       System.out.write(buf, 0, len); 
      } 
     } 
     is.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
}