2012-03-30 4 views
21

Wenn ich eine große Zip-Datei (250 MB) über die ZipFile-Klasse öffne und versuche, die Einträge zu lesen. Dies funktioniert gut auf 2.x im Emulator und echte Hardware. Wenn ich den genauen Code auf meinem Tablet (Asus Transformer unter 4.0.3) oder dem Emulator (3.2) verwende, kann ich keine Einträge lesen. Die size() -Funktion der ZipFile-Klasse gibt immer Null zurück und ZipFile gibt keine zip-Einträge zurück. Selbst die Zip-App, die mit dem ROM auf meinem Tablet geliefert wird, kann keine Einträge lesen. Die Zip-Datei ist nicht beschädigt. Ich habe nachgeschaut.Android 3.x + Java ZipFile-Klasse - Kann ZipEntries nicht aus großen Dateien lesen

Der Code zum Lesen von ZipFile funktioniert auf allen Versionen mit kleineren Zip-Dateien. Was hat sich zwischen 2.x und 3.x/4.x geändert?

Meine Testdatei ist die C64Music.zip aus der HighVoltage Sid Collection. Es enthält über 40.000 Dateien und ist ca. 250MB.

Ich habe keine Ahnung, wo ich hinschauen soll.

+0

Haben Sie versucht, andere Zip-Dateien auf Ihrem Asus oder Emulator mit 3.x/4.x zu lesen? Ist das Problem nur mit dieser Zip-Datei? –

+0

Schluckst du irgendwelche Ausnahmen? Wenn nicht, gibt getName() den Namen der ZIP-Datei zurück? (Einfacher Test, könnte aber etwas Überraschendes ergeben). Erhalten Sie andere Ergebnisse, wenn Sie den Reißverschluss mit oder ohne das OPEN_READ-Flag öffnen? –

+0

Ich bin mir nicht sicher, könnten Sie versuchen, mit 'JarFile'? ... –

Antwort

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(); 
    } 
0

In 3.x/4.x wurden viele Änderungen vorgenommen, um einen Missbrauch des UI-Threads zu verhindern. Daher ist es möglich, dass Ihre App abstürzt, da Sie den teuren Datenträger-E/A-Vorgang nicht auf einen separaten Thread entladen.

2

Dies ist ein bekanntes Problem mit der Android ZipFile Implementierung:

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

Grundsätzlich Zip-Dateien nur bis zu 65k Einträgen unterstützen. Es gibt eine erweiterte Version des Zip-Dateiformats namens Zip64, das eine größere Anzahl von Einträgen unterstützt. Leider kann ZipFile auf Android Zip64 nicht lesen. Sie werden wahrscheinlich feststellen, dass die C64Music.zip-Datei im Zip64-Format ist

Eine Umgehung ist die Verwendung der Apache Commons Compress-Bibliothek anstelle der nativen Implementierung. Ihre Version von ZipFile unterstützt Zip64: http://commons.apache.org/compress/apidocs/org/apache/commons/compress/archivers/zip/ZipFile.html