2011-07-22 10 views
8

Mam pytanie, które wydaje się łatwe, ale nie mogę sprawić, by działało poprawnie.Android: uzyskać liczbę plików w Zip?

Mam plik zip w folderze "zasoby", który muszę rozpakować i mam ProgessBar, w którym chcę wyświetlić użytkownikowi postępy w działaniu.

Mam wszystko działa, ale chcę ustawić maksymalną wartość ProgessBar na liczbę plików w pliku zip. Liczba plików w tym folderze będzie się czasami zmieniać, więc chcę, aby wartość parametru ProgessBar była względna do liczby plików znajdujących się w pliku ZIP.

Używam interfejsu ZipInputStream -API, ale wygląda na to, że nie ma sposobu na uzyskanie liczby plików w pliku zip. Jedynym sposobem mogę od pomyśleć, to w ten sposób:

ZipInputStream zin = new ZipInputStream(getAssets().open(
           "myFile.zip")); 
    int numFiles = 0; 
    int increment = 0; 
    while (zin.getNextEntry() != null) { 
    numFiles++; 
    } 

    ZipEntry ze = null; 
    //Set the Max..value here.. 
    progessBar.setMax(numFiles);     
    while ((ze = zin.getNextEntry()) != null) { 
     increment++; 
     progessBar.setProgress(increment); 
    } 

To działa, ale o dwóch pętli while wydaje się nieco zbędny, które są w zasadzie robi to samo.

Wiem, że istnieje ZipFile -API o metodzie size(), ale wymaga ona ścieżki do pliku, a ponieważ mój plik znajduje się w folderze "aktywów", jestem pewien, że jest to jedyny sposób na odczytanie ten katalog jest przesyłany strumieniowo.

Czy jest dla mnie sposób, aby to osiągnąć?

Odpowiedz

3

Podstawowy problem polega na tym, że przed rozpoczęciem czytania pliku musisz wykonać progressBar.setMax() i ustawiasz wartość maksymalną na podstawie liczby plików.

Czy myślisz o zrobieniu progressBar.setMax(zin.getSize()), a następnie śledzeniu, ile bajtów napisałeś, gdy dzwonisz pod numer progressBar.setProgress(), zamiast liczby przeczytanych plików? To powinno rozwiązać twój problem i da ci (imho) dokładniejszy pasek postępu.

+1

, ale co, jeśli jeden plik ma rozmiar 10 kB, a drugi 10 kb, aw archiwum są tylko dwa pliki? – pleerock

+3

Nie będzie działać, ponieważ ZipInputStream nie ma żadnej metody o nazwie getSize. – melbic

4

Użyj ZipFile API, istnieje metoda size, która zwraca numer ZipEntries w ZipFile. Możesz czytać z folderu zasobów.

przykład:

int zipEntriesCount(String path) throws IOException { 

    ZipFile zf= new ZipFile(path); 
    return zf.size(); 
} 
8

Dzięki za odpowiedzi. Do czego doszło, używając interfejsu API: AssetFileDescriptor, aby pobrać rozmiar pliku zip i ustawić go jako wartość ProgessBar.setMax(). Następnie, gdy przeglądam zawartość zip, zwiększam postęp, używając każdego rozmiaru pliku wpisów. Działa to, ale mam tylko jedną obawę, że wartości AssetFileDescriptor.getLength(), a także wartości ZipEntry.getSize(), zwracają wartość long, więc zmuszeni są przesłać je do liczby całkowitej, zanim będę mógł ustawić max i/lub inkrementację ProgessBar, więc istnieje niewielka wartość. Możliwe, że mogę przeciążyć wartość całkowitą powodującą wyjątek, ale nie jest to prawdopodobne, ponieważ nie oczekuję, że moje rozmiary plików będą coraz większe niż maksymalna liczba całkowita.

ZipInputStream zin = new ZipInputStream(getAssets().open(
          "myFile.zip")); 
ZipEntry ze = null; 
AssetFileDescriptor mydisc = getAssets().openFd("myFile.zip"); 
//Size of the zip package 
long size = mydisc.getLength(); 
long increment = 0; 
dialog.setMax((int) size); 
while ((ze = zin.getNextEntry()) != null) { 
    increment += (int) ze.getSize(); 
    progessBar.setProgess((int)increment); 
    //do more stuff.. 
} 

Nie najlepsze rozwiązanie, ale działa.

Jestem świadomy interfejsu API ZipFile, ale wymaga to podania ciągu znaków, ale nie jestem pewien, co to jest ścieżka do tego katalogu ani jak go uzyskać?