简体   繁体   中英

How to access a zip file into a zip file in Java

I'm trying to read .srt files that are located in zip file itself located in a zip file. I succeed to read .srt files that were in a simple zip with the extract of code below :

    for (Enumeration enume = fis.entries(); enume.hasMoreElements();) {
                ZipEntry entry = (ZipEntry) enume.nextElement();
                fileName = entry.toString().substring(0,entry.toString().length()-4);
try {
                    InputStream in = fis.getInputStream(entry);
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String ext = entry.toString().substring(entry.toString().length()-4, entry.toString().length());

But now i don't know how i could get to the zip file inside the zip file. I tried using ZipFile fis = new ZipFile(filePath) with filePath being the path of the zip file + the name of zip file inside. It didn't recognize the path so i don't know if i am clear.

Thanks.

ZipFile only works with real files, because it's intended for use as a random access mechanism which needs to be able to seek directly to specific locations in the file to read entries by name. But as VGR suggests in the comments, while you can't get random access to the zip-inside-a-zip you can use ZipInputStream , which provides strictly sequential access to the entries and works with any InputStream of zip-format data.

However, ZipInputStream has a slightly odd usage pattern compared to other streams - calling getNextEntry reads the entry metadata and positions the stream to read that entry's data, you read from the ZipInputStream until it reports EOF, then you (optionally) call closeEntry() before moving on to the next entry in the stream.

The critical point is that you must not close() the ZipInputStream until you have finished reading the final entry, so depending what you want to do with the entry data you might need to use something like the commons-io CloseShieldInputStream to guard against the stream getting closed prematurely.

try(ZipInputStream outerZip = new ZipInputStream(fis)) {
  ZipEntry outerEntry = null;
  while((outerEntry = outerZip.getNextEntry()) != null) {
    if(outerEntry.getName().endsWith(".zip")) {
      try(ZipInputStream innerZip = new ZipInputStream(
                  new CloseShieldInputStream(outerZip))) {
        ZipEntry innerEntry = null;
        while((innerEntry = innerZip.getNextEntry()) != null) {
          if(innerEntry.getName().endsWith(".srt")) {
            // read the data from the innerZip stream
          }
        }
      }
    }
  }
}

Find the code to extract .zip files recursively:

public void extractFolder(String zipFile) throws ZipException, IOException {
System.out.println(zipFile);
int BUFFER = 2048;
File file = new File(zipFile);

ZipFile zip = new ZipFile(file);
String newPath = zipFile.substring(0, zipFile.length() - 4);

new File(newPath).mkdir();
Enumeration zipFileEntries = zip.entries();

// Process each entry
while (zipFileEntries.hasMoreElements())
{
    // grab a zip file entry
    ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
    String currentEntry = entry.getName();
    File destFile = new File(newPath, currentEntry);
    //destFile = new File(newPath, destFile.getName());
    File destinationParent = destFile.getParentFile();

    // create the parent directory structure if needed
    destinationParent.mkdirs();

    if (!entry.isDirectory())
    {
        BufferedInputStream is = new BufferedInputStream(zip
        .getInputStream(entry));
        int currentByte;
        // establish buffer for writing file
        byte data[] = new byte[BUFFER];

        // write the current file to disk
        FileOutputStream fos = new FileOutputStream(destFile);
        BufferedOutputStream dest = new BufferedOutputStream(fos,
        BUFFER);

        // read and write until last byte is encountered
        while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
            dest.write(data, 0, currentByte);
        }
        dest.flush();
        dest.close();
        is.close();
    }

    if (currentEntry.endsWith(".zip"))
    {
        // found a zip file, try to open
        extractFolder(destFile.getAbsolutePath());
    }
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM