Tuesday, October 25, 2011

Recursively unzip archive in memory

In addition to the previous post about recursive unzipping you may need to unzip archive in memory. In this situation the following code will help you:

package com.test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Unzipper {
 private final static int BUFFER_SIZE = 2048;
 private final static String ZIP_EXTENSION = ".zip";
 
 public static void main(String[] args) throws IOException {
  File f = new File("/home/anton/test/test.zip");
  FileInputStream fis = new FileInputStream(f);
  BufferedInputStream bis = new BufferedInputStream(fis);
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  BufferedOutputStream bos = new BufferedOutputStream(baos);
  byte[] buffer = new byte[BUFFER_SIZE];
  while (bis.read(buffer, 0, BUFFER_SIZE) != -1) {
   bos.write(buffer);
  }
  bos.flush();
  bos.close();
  bis.close();
  List<ByteArrayOutputStream> listFiles =  unzip(baos);
 }

 public static List<ByteArrayOutputStream> unzip(
   ByteArrayOutputStream zippedFileOS) {
  try {
   ZipInputStream inputStream = new ZipInputStream(
     new BufferedInputStream(new ByteArrayInputStream(
       zippedFileOS.toByteArray())));
   ZipEntry entry;

   List<ByteArrayOutputStream> result = new ArrayList<ByteArrayOutputStream>();
   while ((entry = inputStream.getNextEntry()) != null) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    System.out.println("\tExtracting entry: " + entry);
    int count;
    byte data[] = new byte[BUFFER_SIZE];

    if (!entry.isDirectory()) {
     BufferedOutputStream out = new BufferedOutputStream(
       outputStream, BUFFER_SIZE);
     while ((count = inputStream.read(data, 0, BUFFER_SIZE)) != -1) {
      out.write(data, 0, count);
     }
     out.flush();
     out.close();
     // recursively unzip files
     if (entry.getName().toLowerCase().endsWith(ZIP_EXTENSION)) {
      result.addAll(unzip(outputStream));
     } else {
      result.add(outputStream);
     }
    }
   }
   inputStream.close();
   return result;
  } catch (Exception e) {
   throw new RuntimeException(e);
  }
 }
}

You may also want to check how to recursively unzip archive to file