22

If I open a big zip file (250MB) via the ZipFile class and try to read the entries. This works fine on 2.x in the emulator and real hardware. If I use the exact some code on my tablet (Asus Transformer running 4.0.3) or the emulator (3.2), I can't read any entries. The size() function of the ZipFile class always returns zero and the ZipFile does not return any zip entries. Even the a zip app that comes with the ROM on my tablet can't read any entries. The zip file is not damaged. I checked it.

The code to read from ZipFile works fine on all version with smaller zip files. What has changed between 2.x and 3.x/4.x??

My Testfile is the C64Music.zip from the HighVoltage Sid Collection. It contains over 40.000 files and is around 250MB.

I have no clue where to look at.

Chimera
  • 5,884
  • 7
  • 49
  • 81
wbb
  • 266
  • 1
  • 3
  • Have you tried to read other zip files on your Asus or emulator running 3.x/4.x? Is the problem only with this zip file? – David Wasser May 24 '12 at 09:11
  • Are you swallowing any exceptions? If not, does getName() return the name of the zipfile? (Simple test, but might turn up something surprising). Do you get any different results if you open the zip with or without the OPEN_READ flag? – JD. Jul 03 '12 at 16:41
  • I'm not sure, could you try with `JarFile`?… –  Jul 10 '12 at 13:52
  • Try a zip file that has less than 32k files in it. – Nathan Moinvaziri Jul 10 '12 at 20:07
  • Have you looked at the file on the file system on the transformer tab? You should do that and compare MD5sums. – hsanders Jul 11 '12 at 21:03

3 Answers3

2

This is a known issue with the android ZipFile implementation:

http://code.google.com/p/android/issues/detail?id=23207

Basically zip files only support up to 65k entries. There is an extended version of the zip file format called Zip64, which supports a larger number of entries. Unfortunately ZipFile on android cannot read Zip64. You will probably find that the C64Music.zip file is in the Zip64 format

A work around is to use the Apache Commons Compress library instead of the native implementation. Their version of ZipFile supports Zip64: http://commons.apache.org/compress/apidocs/org/apache/commons/compress/archivers/zip/ZipFile.html

Luke Sleeman
  • 1,636
  • 1
  • 16
  • 27
0
    public class Compress { 

  private static final int BUFFER = 2048;  
  private String[] _files; 
  private String _zipFile;  
  public Compress(String[] files, String zipFile) { 
    _files = files; 
    _zipFile = zipFile; 
  }  
  public void zip() { 
    try  { 
      BufferedInputStream origin = null; 
      FileOutputStream dest = new FileOutputStream(_zipFile);  
      ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest)); 
      byte data[] = new byte[BUFFER]; 
      for(int i=0; i < _files.length; i++) { 
        Log.v("Compress", "Adding: " + _files[i]); 
        FileInputStream fi = new FileInputStream(_files[i]); 
        origin = new BufferedInputStream(fi, BUFFER); 
        ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1)); 
        out.putNextEntry(entry); 
        int count; 
        while ((count = origin.read(data, 0, BUFFER)) != -1) { 
          out.write(data, 0, count); 
        } 
        origin.close(); 
      } 

      out.close(); 
    } catch(Exception e) { 
      e.printStackTrace(); 
    } 

  } 

}

Call Compress like given below where you want to zip a file  :----

String zipFilePath = "fileName.zip";
File zipFile = new File(zipFilePath);
String[] files = new String[] {"/sdcard/fileName"};
if(!zipFile.exists()){
    new Compress(files, zipFilePath).zip();
   }
vikas
  • 139
  • 1
  • 8
0

A lot of changes were made in 3.x/4.x to prevent abuse against the UI thread. Therefore, it is possible that your app is crashing because you are not offloading the expensive disk I/O operation to a separate Thread.

Alex Lockwood
  • 83,063
  • 39
  • 206
  • 250