2015-04-08 2 views
5

Я могу пройти через ZipInputStream, но перед началом итерации я хочу получить конкретный файл, который мне нужен во время итерации. Как я могу это сделать?Получение определенного файла из ZipInputStream

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

Я не понимаю ... Итерируйте записи, пока не получите тот, который вы хотите, а затем обработайте его? –

+1

Сначала перейдите к файлу и сохраните его так, как вы хотите. Затем просто повторите попытку. – Bubletan

+0

Существует также ZipFile (java <7) и Zip-файловая система, начиная с Java7 (хотя это невозможно из ZipInputStream :)), поэтому это не ответ на вопрос – GPI

ответ

2

Если myInputStream вы работаете с помощью реального файла на диске, то вы можете просто использовать java.util.zip.ZipFile вместо этого, который поддерживается RandomAccessFile и обеспечивает прямой доступ к записям zip по имени. Но если все, что у вас есть, это InputStream (например, если вы обрабатываете поток непосредственно при получении из сетевого сокета или аналогичного), вам придется выполнять свою собственную буферизацию.

Вы можете скопировать поток во временный файл, затем открыть этот файл с помощью ZipFile или если вы заранее знаете максимальный размер данных (например, для HTTP-запроса, который объявляет егоспереди), вы можете использовать BufferedInputStream, чтобы сохранить его в памяти до тех пор, пока вы не найдете требуемую запись.

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

(я не проверял этот код сам, вы можете обнаружить, что необходимо использовать что-то вроде Викисклада гипергликемии CloseShieldInputStream в период между bufIn и первым zipIn, чтобы первый поток молнии, чтобы закрыть без закрытия базовый bufIn, прежде чем перематывать его).

+0

Это точно мое дело. благодаря – Jils

1

Посмотрите на 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

В методе 'searchImage' отсутствует возвращаемый тип 'ZipInputStream'. – Rooky

3

использовать метод GetName() на ZipEntry, чтобы получить файл, который вы хотите.

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

С Java 7 и далее, вы лучше использовать ZipFile вместо ZipStream, если вы хотите только один файл, и у вас есть файл для чтения из:

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

Для вашего первого кода: см. Мой ответ tim_yates. Для вашего второго кода: я думал, что что-то похожее на ZipFile. Поэтому для моего случая следует использовать ZipFile. – Jils