2015-04-08 9 views
5

Ich kann durch ZipInputStream gehen, aber vor Beginn der Iteration möchte ich eine bestimmte Datei, die ich während der Iteration brauche. Wie kann ich das machen?Bestimmte Datei von ZipInputStream erhalten

ZipInputStream zin = new ZipInputStream(myInputStream) 
while ((entry = zin.getNextEntry()) != null) 
{ 
    println entry.getName() 
} 
+2

Ich verstehe nicht ... Iterate die Einträge, bis Sie diejenige, die Sie wollen zu bekommen, ist es dann verarbeiten? –

+1

Zuerst iterieren Sie die Datei und speichern Sie sie wie Sie wollen. Dann wiederhole es einfach nochmal. – Bubletan

+0

Es gibt auch ZipFile (java <7) und das Zip-Dateisystem ab Java7 (obwohl das nicht möglich ist von einem ZipInputStream :)), deshalb ist dies keine Antwort auf die Frage – GPI

Antwort

2

Wenn die myInputStream Sie arbeiten mit von einer realen Datei auf der Festplatte kommt, dann können Sie einfach java.util.zip.ZipFile stattdessen verwenden, die von einem RandomAccessFile und bietet einen direkten Zugang zu den Zip-Einträge mit Namen unterstützt wird. Aber wenn alles, was Sie haben, ist ein InputStream (zum Beispiel, wenn Sie den Strom sind die Verarbeitung direkt auf den Eingang von einer Netzwerkbuchse oder ähnlich), dann werden Sie Ihre eigene Pufferung zu tun haben.

Sie könnten den Stream in eine temporäre Datei kopieren, dann öffnen Sie diese Datei mit ZipFile, oder wenn Sie die maximale Größe der Daten im Voraus kennen (zB für eine HTTP-Anfrage, die seine Content-Length im Voraus deklariert) könnten Sie a BufferedInputStream, um es im Speicher zu puffern, bis Sie den gewünschten Eintrag gefunden haben.

BufferedInputStream bufIn = new BufferedInputStream(myInputStream); 
bufIn.mark(contentLength); 
ZipInputStream zipIn = new ZipInputStream(bufIn); 
boolean foundSpecial = false; 
while ((entry = zin.getNextEntry()) != null) { 
    if("special.txt".equals(entry.getName())) { 
    // do whatever you need with the special entry 
    foundSpecial = true; 
    break; 
    } 
} 

if(foundSpecial) { 
    // rewind 
    bufIn.reset(); 
    zipIn = new ZipInputStream(bufIn); 
    // .... 
} 

(ich diesen Code selbst nicht getestet haben, können Sie es finden, notwendig so etwas wie die commons-io CloseShieldInputStream zwischen dem bufIn und dem ersten zipIn, verwenden die erste Zip-Stream zu ermöglichen, ohne Schließung zu schließen das zugrunde liegende bufIn bevor du es zurückgespult hast).

+0

Das ist genau mein Fall. Vielen Dank – Jils

1

Blick auf Finding a file in zip entry

ZipFile file = new ZipFile("file.zip"); 
ZipInputStream zis = searchImage("foo.png", file); 

public searchImage(String name, ZipFile file) 
{ 
    for (ZipEntry e : file.entries){ 
    if (e.getName().endsWith(name)){ 
     return file.getInputStream(e); 
    } 
    } 

    return null; 
} 
+0

Der Methode 'searchImage' fehlt der Rückgabetyp 'ZipInputStream'. – Rooky

3

verwenden Sie die Methode getName() auf ZipEntry Sie die gewünschte Datei zu erhalten.

ZipInputStream zin = new ZipInputStream(myInputStream) 
String myFile = "foo.txt"; 
while ((entry = zin.getNextEntry()) != null) 
{ 
    if (entry.getName().equals(myFileName)) { 
     // process your file 
     // stop looking for your file - you've already found it 
     break; 
    } 
} 

Von Java 7 ab, Sie sind besser dran mit ZipFile statt ZipStream, wenn Sie nur eine Datei wollen, und Sie haben eine Datei aus zu lesen:

ZipFile zfile = new ZipFile(aFile); 
String myFile = "foo.txt"; 
ZipEntry entry = zfile.getEntry(myFile); 
if (entry) { 
    // process your file   
} 
+0

Für Ihren ersten Code: siehe meine Antwort auf tim_yates. Für Ihren zweiten Code: Ich dachte, dass ZipFile etwas Ähnliches hat. Also für meinen Fall sollte ZipFile verwenden. – Jils