2012-03-30 16 views
21

Jeśli otworzę duży plik zip (250 MB) za pośrednictwem klasy ZipFile i spróbuję odczytać wpisy. Działa to dobrze na 2.x w emulatorze i na prawdziwym sprzęcie. Jeśli użyję dokładnego kodu na moim tablecie (Asus Transformer z 4.0.3) lub emulatorze (3.2), nie mogę odczytać żadnych wpisów. Funkcja size() klasy ZipFile zawsze zwraca zero, a ZipFile nie zwraca żadnych pozycji zip. Nawet aplikacja zip, która jest dostarczana z ROMem na moim tablecie, nie może odczytać żadnych wpisów. Plik zip nie jest uszkodzony. Sprawdziłem to.Android 3.x + Java ZipFile Class - Nie można odczytać ZipEntries z dużych plików

Kod do odczytu z ZipFile działa dobrze we wszystkich wersjach z mniejszymi plikami zip. Co zmieniło się pomiędzy 2.x a 3.x/4.x?

Mój plik testowy to plik C64Music.zip z kolekcji HighVoltage Sid. Zawiera ponad 40 000 plików i wynosi około 250 MB.

Nie mam pojęcia, gdzie patrzeć.

+0

Czy próbowałeś czytać inne pliki zip na swoim Asusie lub emulatorze z 3.x/4.x? Czy problem dotyczy tylko tego pliku zip? –

+0

Połkniesz jakieś wyjątki? Jeśli nie, to czy funkcja getName() zwraca nazwę pliku zip? (Prosty test, ale może pojawić się coś zaskakującego). Czy otrzymasz inne wyniki, jeśli otworzysz zip z flagą OPEN_READ lub bez niej? –

+0

Nie jestem pewien, czy mógłbyś spróbować z 'JarFile'? ... –

Odpowiedz

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

Wiele zmian dokonano w 3.x/4.x, aby zapobiec nadużyciom wobec wątku UI. Dlatego możliwe jest, że twoja aplikacja ulega awarii, ponieważ nie przenosisz kosztownej operacji na dysku I/O do osobnego Thread.

2

Jest to znany problem z android realizacji zipfile:

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

Zasadniczo pliki zip tylko obsługiwać do 65k wpisów. Istnieje rozszerzona wersja formatu pliku ZIP o nazwie Zip64, która obsługuje większą liczbę wpisów. Niestety ZipFile na Androida nie może odczytać Zip64. Prawdopodobnie plik C64Music.zip jest w formacie Zip64:

Praca polega na użyciu biblioteki Compress Apache Commons zamiast natywnej implementacji. Ich wersja ZipFile obsługuje Zip64: http://commons.apache.org/compress/apidocs/org/apache/commons/compress/archivers/zip/ZipFile.html

Powiązane problemy