Прочитать zip-файл внутри zip-файла

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

НАПРИМЕР.:

abc.zip
    |
      documents/bcd.zip

Как прочитать zip-файл внутри zip-файла?

 Sujay02 июл. 2012 г., 05:32
что ты имеешь в виду под чтением? Вы хотите извлечь bcd.zip?

Ответы на вопрос(4)

В следующем фрагменте кода перечислены записи файла ZIP внутри другого файла ZIP. Приспособьте это к своим потребностям.ZipFile использованияZipInputStreams под капотом.

Фрагмент кода используетApache Commons IOконкретноIOUtils.copy.

public static void readInnerZipFile(File zipFile, String innerZipFileEntryName) {
    ZipFile outerZipFile = null;
    File tempFile = null;
    FileOutputStream tempOut = null;
    ZipFile innerZipFile = null;
    try {
        outerZipFile = new ZipFile(zipFile);
        tempFile = File.createTempFile("tempFile", "zip");
        tempOut = new FileOutputStream(tempFile);
        IOUtils.copy( //
                outerZipFile.getInputStream(new ZipEntry(innerZipFileEntryName)), //
                tempOut);
        innerZipFile = new ZipFile(tempFile);
        Enumeration<? extends ZipEntry> entries = innerZipFile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            System.out.println(entry);
            // InputStream entryIn = innerZipFile.getInputStream(entry);
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // Make sure to clean up your I/O streams
        try {
            if (outerZipFile != null)
                outerZipFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        IOUtils.closeQuietly(tempOut);
        if (tempFile != null && !tempFile.delete()) {
            System.out.println("Could not delete " + tempFile);
        }
        try {
            if (innerZipFile != null)
                innerZipFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static void main(String[] args) {
    readInnerZipFile(new File("abc.zip"), "documents/bcd.zip");
}
 20 июл. 2018 г., 23:33
Отлично, но 3 Мб только дляIOUtils.copy функция, у которой есть 2 строки, seriosly?
 22 февр. 2013 г., 12:41
Идеальное решение, именно то, что я хотел и ломал голову часами. Вы сделали мой день. Огромное спасибо.
 06 сент. 2012 г., 16:35
Офигенно чувак .... спасибо ... !!!!!
 Prakash Reddy Barri02 июл. 2012 г., 11:35
Отлично Это то, что я ищу. Большое спасибо братан
 16 сент. 2014 г., 22:47
Обратите внимание, что это можно сделать без временного файла. Вам нужно будет создать оригиналZipInputStream от"abc.zip" файл затем откройте новыйZipInputStream дляZipEntry соответствующий файлу"documents/bcd.zip", Обязательно заверните оригиналZipInputStream сInputStream что позволяет избежать закрытияInputStream управляемый новымZipInputStream, ЕдинственныйInputStream вам нужно будет закрыть оригинал.

Я написал код, который может распаковать все ZIP-файлы внутри ZIP-файла. Он может даже распаковать до n уровней сжатия. Как, например, если бы у вас был zip-файл внутри zip-файла, внутри zip-файла (и т. Д.) Он извлек бы все из них. Используйте метод zipFileExtract этого класса и передайте исходный zip-файл и каталог назначения в качестве аргумента.

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class RecursiveFileExtract {
    private static final int BUFFER_SIZE = 4096;
    private static Queue<File> current;
    private static List<File> visited;

    public static void zipFileExtract(File sourceZipFile, File destinationDirectory) {
        Path temp = null;
        if(!destinationDirectory.exists())
        {
            destinationDirectory.mkdirs();
        }
        try {
            temp = Files.move(Paths.get(sourceZipFile.getAbsolutePath()), Paths.get(destinationDirectory.getAbsolutePath()+File.separator+sourceZipFile.getName()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        File zipFile = new File(temp.toAbsolutePath().toString());
        current = new ConcurrentLinkedQueue<>();
        visited = new ArrayList<>();
        current.add(zipFile);
        do {
            unzipCurrent();
            zipFinder(destinationDirectory);
        }
        while (!current.isEmpty());
    }

    private static void zipFinder(File directory) {
        try {
            if (directory != null) {
                File fileArray[] = directory.listFiles();
                if (fileArray != null) {
                    for (File file : fileArray) {
                        if (file != null) {
                            if (file.isDirectory()) {
                                zipFinder(file);
                            } else {
                                if (file.getName().endsWith(".zip")) {
                                    if (!visited.contains(file)) {
                                        current.add(file);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }
    }

    private static void unzipCurrent() {
        try {
            while (!current.isEmpty()) {
                File file = current.remove();
                visited.add(file);
                File zipDirectory = new File(file.getParentFile().getAbsolutePath());
                unzip(file.getAbsolutePath(), zipDirectory.getAbsolutePath());
            }
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }
    }

    public static void unzip(String zipFilePath, String destDirectory) {
        try {
            ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
            ZipEntry entry = zipIn.getNextEntry();

            while (entry != null) {
                String filePath = destDirectory + File.separator + entry.getName();
                if (!entry.isDirectory()) {
                    extractFile(zipIn, filePath);
                } else {

                    File dir = new File(filePath);
                    Boolean result = dir.mkdir();
                }
                zipIn.closeEntry();
                entry = zipIn.getNextEntry();
            }
            zipIn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void extractFile(ZipInputStream zipIn, String filePath) {
        try {
            File file = new File(filePath);
            File parentFile = file.getParentFile();
            if (!parentFile.exists()) {
                Boolean result = parentFile.mkdirs();
                if (!result) {
                    throw new Exception();
                }
            }
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
            byte[] bytesIn = new byte[BUFFER_SIZE];
            int read = 0;
            while ((read = zipIn.read(bytesIn)) != -1) {
                bos.write(bytesIn, 0, read);
            }
            bos.close();
        } catch (Exception e) {
           System.out.println(e.getLocalizedMessage());
        }
    }
}

Наконец-то он начал исправлять ответ Манаса Маджи. Минимальное решение:

import java.io.*;
import java.nio.file.*;
import java.util.zip.*;
import org.slf4j.*;

public void readZipFileRecursive(final Path zipFile) {
  try (final InputStream zipFileStream = Files.newInputStream(zipFile)) {
    this.readZipFileStream(zipFileStream);
  } catch (IOException e) {
    LOG.error("error reading zip file %s!", zipFile, e);
  }
}

private void readZipFileStream(final InputStream zipFileStream) {
  final ZipInputStream zipInputStream = new ZipInputStream(zipFileStream);
  ZipEntry zipEntry;
  try {
    while ((zipEntry = zipInputStream.getNextEntry()) != null) {
      LOG.info("name of zip entry: {}", zipEntry.getName());
      if (!zipEntry.isDirectory() && zipEntry.getName().endsWith(".zip")) {
        this.readZipFileStream(zipInputStream); // recursion
      }
    }
  } catch (IOException e) {
    LOG.error("error reading zip file stream", e);
  }
}

Уход: не закрывать поток рекурсивным методом.

Если вы хотите просматривать zip-файлы внутри zip-файлов рекурсивно,

    public void lookupSomethingInZip(InputStream fileInputStream) throws IOException {
        ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);
        String entryName = "";
        ZipEntry entry = zipInputStream.getNextEntry();
        while (entry!=null) {
            entryName = entry.getName();
            if (entryName.endsWith("zip")) {
                //recur if the entry is a zip file
                lookupSomethingInZip(zipInputStream);
            }
            //do other operation with the entries..

            entry=zipInputStream.getNextEntry();
        }
    }

Вызовите метод с потоком ввода файла, полученным из файла -

File file = new File(name);
lookupSomethingInZip(new FileInputStream(file));
 21 нояб. 2017 г., 17:04
повторить на том же Zip? Нет пользы ..
 25 февр. 2019 г., 08:45
Я исправил сломанную рекурсию в этом ответе:stackoverflow.com/a/54861562/5777603 Спасибо Манас Маджи за идею :)

Ваш ответ на вопрос