2015-04-08 42 views
5

Mogę przejść przez ZipInputStream, ale przed rozpoczęciem iteracji chcę uzyskać konkretny plik, który jest mi potrzebny podczas iteracji. Jak mogę to zrobić?Uzyskiwanie określonego pliku z ZipInputStream

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

Nie rozumiem ... Iteruj wpisy, dopóki nie uzyskasz tego, którego chcesz, a następnie przetworzę? –

+1

Najpierw przejdź do pliku i zapisz go tak, jak chcesz. Następnie powtórz ponownie. – Bubletan

+0

Istnieje również ZipFile (java <7) i system plików Zip zaczynający się od Java7 (chociaż nie jest to możliwe z ZipInputStream :)), dlatego nie jest to odpowiedź na pytanie – GPI

Odpowiedz

2

Jeśli myInputStream pracujesz Pochodzi z prawdziwego pliku na dysku, więc możesz po prostu użyć java.util.zip.ZipFile, który jest wspierany przez RandomAccessFile i zapewnia bezpośredni dostęp do wpisów zip po nazwie. Ale jeśli wszystko, co masz, to InputStream (np. Jeśli przetwarzasz strumień bezpośrednio na odbiorze z gniazda sieciowego lub podobnego), musisz wykonać własne buforowanie.

Można skopiować strumień do pliku tymczasowego, a następnie otworzyć ten plik za pomocą ZipFile, lub jeśli znasz maksymalny rozmiar danych z wyprzedzeniem (np żądania HTTP, który deklaruje Content-Length z góry) można użyć BufferedInputStream, aby buforować go w pamięci, dopóki nie znajdziesz wymaganego wpisu.

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); 
    // .... 
} 

(nie mam sobie przetestowane tego kodu, może się okazać, że to niezbędne do korzystania z czegoś podobnego do świetlicy-IO CloseShieldInputStream w między bufIn i pierwszym zipIn, aby umożliwić pierwszy strumień zip, aby zamknąć bez zamykania podstawowy bufIn, zanim go przewiniesz).

+0

To jest dokładnie moja sprawa. Dzięki – Jils

1

Spójrz na 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

W metodzie "searchImage" brakuje typu zwracanego "ZipInputStream". – Rooky

3

użyć metody getName() na ZipEntry aby uzyskać żądany plik.

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; 
    } 
} 

z Java 7 r, jesteś lepiej wyłączyć za pomocą zipfile zamiast ZipStream jeśli tylko chcesz jeden plik i masz plik do zapoznania się z:

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

Dla twojego pierwszego kodu: zobacz moją odpowiedź na tim_yates. Dla twojego drugiego kodu: Myślałem, że było coś podobnego do ZipFile. Tak więc w moim przypadku powinien użyć ZipFile. – Jils