7

To unzip zip file I've used classes from package java.util.zip* by refering this and it works correctly however to unzip a file of 40MB it takes 59 seconds. When I tried same zip file on iPhone project (we are developing app for both platforms - Android & iPone & that have functionality to unzip zip file & save unzipped content to SDCARD-Android or document directory - iPhone ), it takes only 14 seconds. The iphone app uses ziparchive.

So my question are:

1.From above experiment it clears that unzipping & file write operation to SDCARD in Java consumes more time as compared to iPhone app, so I decided to use C/C++ level unzipping & file write operation using NDK. Is this right choice ?

2.I have searched on google, stackoverflow & some suggested to use minizip but there no sufficient help on how to use minizip in android. Is anyboday have tried minizip for android ?

3.I also tried NDK development for libz to achieve my goal, as Libz is added in NDK but not getting how to use it. Is anybody tried libz in NDK?

4.Is there any other Framework in Java or C/C++ that unzip large zip file & write them to SDCARD in less time ?

Please help me.

Here is my Java Unzip Code :

public String unzip() {

    String result;

    try {

        FileInputStream fin = new FileInputStream(this.filePath);
        ZipInputStream zin = new ZipInputStream(fin);
        ZipEntry ze = null;

        while ((ze = zin.getNextEntry()) != null) {

            Log.v("Unzip", "Unzipping " + ze.getName());

            if (ze.isDirectory()) {
                _dirChecker(ze.getName());
            } else {

                // Read 16 k at a time 
                byte[] buffer = new byte[16*1024];
                 int read;

                FileOutputStream fout = new FileOutputStream(this.location+ "/" + ze.getName());

                while ((read = zin.read(buffer)) != -1)
                {
                    fout.write(buffer, 0, read);
                }


                zin.closeEntry();
                fout.close();
            }

        }

        zin.close();
        result = "success";

    } catch (Exception e) {
        Log.e("unzip", "unzip", e);
        result = "failure";
    }

    return result;
}
Community
  • 1
  • 1
sachin003
  • 8,983
  • 4
  • 21
  • 23
  • 3
    I suspect its the SD card part. Writing to SD Cards can be very very slow especially on low end Android phones or cheap SD Cards. The time to unzip can also be suspect on low end Android phones just as it would be on older iPhones as unziping is going to be tied directly to processor speed. – Ryan Poolos Jan 08 '13 at 15:23
  • 2
    To test @RyanPoolos suggestion about the sdcard, try unzipping the files to the apps internal storage (the directory returned by http://developer.android.com/reference/android/content/Context.html#getFilesDir(\) ) and see if the time matches iPhone more closely. The java zip package should be fairly efficient on its own. – Drake Clarris Jan 08 '13 at 15:28
  • You could also time the separate functions for unzipping and writing to see which is actually taking time on both platforms. – Ryan Poolos Jan 08 '13 at 15:31
  • @RyanPoolos Yes, I've tested my code on another device Google Nexus & it takes 50 seconds to unzip the same file. – sachin003 Jan 09 '13 at 06:18
  • @DrakeClarris I tried your suggestion & here is my result: On Samsung Galaxy Ace (Processor Speed is 800 MHz & Ram 278 MB) unzipping & writing speed of 40 MB file is 35 seconds, for Google Nexus S(512 MB RAM, 1GHZ Processor) it takes only 22 seconds. – sachin003 Jan 09 '13 at 07:55
  • @DrakeClarris however I can't store these unzipped files to internal storage of device, my app going to handle more zip files of ebooks of large length. Any suggestion to tackle this ? – sachin003 Jan 09 '13 at 07:58
  • 2
    For the heck of it, unzipped a file on my phone (evo 3d) using the unzip command found in busybox through bash, and a 66MB zip took 12 seconds on internal memory, and 19 seconds on sdcard (class 10 sandisk ultra - way faster than typical class 2 cards). One thing of note, iPhone will always be to an internal NAND, and hence faster than to sdcard on Android, and keep in mind if comparing iPhone 4s or later, it is dual core, and both phones you listed are single core. The nexus S is on par processor and memory wise with iPhone 4. – Drake Clarris Jan 09 '13 at 12:34
  • @DrakeClarris I appreciate your valuable answer, Thanks. – sachin003 Jan 09 '13 at 12:45

4 Answers4

5

Why don't you try this code.It works awesome

    String zipname = "data.zip";
FileInputStream fis = new FileInputStream(zipname);
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;

while ((entry = zis.getNextEntry()) != null) {
  System.out.println("Unzipping: " + entry.getName());

  int size;
  byte[] buffer = new byte[2048];

  FileOutputStream fos = new FileOutputStream(entry.getName());
  BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);

  while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
    bos.write(buffer, 0, size);
  }
  bos.flush();
  bos.close();
}
zis.close();
fis.close();

}

Zubair
  • 436
  • 5
  • 13
4

All of the unzip code eventually ends up in zlib. There is no Java implementation of "deflate" compression in Android core libs.

The only reason java.util.Zip should be slower than a "native" unzip is if the file I/O is done badly, e.g. something is using really small buffers. Looking at the code linked from the question, this is exactly what's happening -- it's operating on individual bytes.

One of the comments on the solution provided a patch that uses a 4K buffer. Drop that in and see what happens to your performance.

fadden
  • 51,356
  • 5
  • 116
  • 166
  • Thanks for your reply, I'm using 16 K buffer size, Please see my Unzip code edited in question. – sachin003 Jan 09 '13 at 06:13
  • This seems to be still valid. I dig the `Zip` code and found that most computationally heavy tasks like `inflateBytes()`, `setDictionary()`,... are native methods in `InflaterInputStream`. There's room for improvement if NDK is fully used, but the exception handling, logging,... could be problematic – Minh Nghĩa Nov 21 '20 at 16:15
1

Try to just write 40Mb file to SDCard and measure time spent. (Almost) all free (or even paid) implementations of zip archive support libraries are based on the same zlib code, which takes most processing speed during the unzipping. Java code should be much slower than native one, so I'd suggest to try NDK unzipping. Also, trying to unzip archive with zero compression level will give you a guess how much time unzipping code takes and how much time is spend on just data copying.

Nickolay Olshevsky
  • 13,706
  • 1
  • 34
  • 48
0
public boolean unzip(String zipfilepath, String destinationdir) {

            try {
                FileInputStream fis = new FileInputStream(zipfilepath);
                ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
                ZipEntry entry;

                while ((entry = zis.getNextEntry()) != null) {
                  System.out.println("Unzipping: " + entry.getName());

                  int size;
                  byte[] buffer = new byte[2048];

                  FileOutputStream fos = new FileOutputStream(destinationdir+ "/" + entry.getName());
                  BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);

                  while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
                    bos.write(buffer, 0, size);
                  }
                  bos.flush();
                  bos.close();
                }
                zis.close();
                fis.close();
                return true;
                }catch(Exception e){
                    return false;
                }
        }



String zipfilepath = context.getFilesDir().getPath()+"/"+myfile.zip;
String  destinationdir = context.getFilesDir().getPath();


unzip(zipfilepath, destinationdir);
Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268