ZipFile внутри ZipFile - PullRequest
       10

ZipFile внутри ZipFile

3 голосов
/ 01 октября 2009

У меня есть zip-файл, который может содержать любое количество zip-файлов внутри (также рекурсивно). Мне нужно перебрать их все.

Прямо сейчас у меня есть функция, которая принимает zipInputStream и zipFile в качестве параметров. Проблема в; если я получаю почтовый индекс внутри другого почтового индекса, я снова вызываю эту функцию рекурсивно. Поэтому я не знаю, как создать объект zipFile для zipfiles внутри другого zipfile. Может кто-нибудь предложить способ сделать это? Вы сталкивались с этим раньше?

Фрагмент будет выглядеть следующим образом.

private void checkZIP(ZipInputStream zInpStream, ZipFile zf) {
  try {  
    ZipEntry zipEntry = zInpStream.getNextEntry();
    while (zipEntry != null) {
       String entryName = zipEntry.getName();

       if(entryName.endsWith(".zip"))
          checkZIP(new ZipInputStream(zf.getInputStream(zipEntry)),<NEW ZIPFILE OBJECT FOR THIS ENTRY>);


       //other files parsing apart from zip.

       zInpStream.closeEntry();
       zipEntry = zInpStream.getNextEntry();
    }
    zInpStream.close();
  } catch(Exception ioe) {
    //catching specific exceptions here. But did not want to put al
  } 
}

РЕДАКТИРОВАТЬ: Мне нужен этот объект почтового файла, потому что. Если я сталкиваюсь с файлом XML, мне нужно создать объект Document. Поэтому, если я передаю обычный метод zipInputStream для метода parse() в DocumentBuilder, он закрывает поток и я не могу использовать его снова. Так что я использовал (ZipFile object).getInputStream(currentEntryForXML) внутри DocumentBuilder parse().

1 Ответ

4 голосов
/ 01 октября 2009

Вы не можете создать ZipFile для zip-файла внутри архива. Но зачем вам этот аргумент в вашем методе? Если вам нужен только поток, просто используйте аргумент zInpStream в качестве параметра contstructor, например

checkZIP(new ZipInputStream(zInpStream));

После вызова zInpStream.getNextEntry () zInpStream уже расположен в начале этой записи и будет читать только эту запись до тех пор, пока не будет вызван getNextEntry ().

Редактировать. Увидел ваше редактирование. Кажется, если вы предотвратите закрытие потока, вам этого будет достаточно. Просто используйте слегка измененный FilterInputStream, который делегирует вызов close () для closeEntry () в zipInputStream, а не в close.

public class ZipGuard extends java.io.FilterInputStream {
    public ZipGuard(ZipInputStream is) {
        super(is);
    }

    @Override
    public void close() throws IOException {
        ((ZipInputStream) in).closeEntry();
    }
}

И создайте этот охранник в checkZip:

checkZip(new ZipInputStream(new ZipGuard(zInpStream)));
...