Skip to content Skip to sidebar Skip to footer

Android: Get Number Of Files Within Zip?

I have a question that seems easy but I cannot seem to get it to work properly. I have a zip file within my 'assets' folder that I need to unzip and I have a ProgessBar in which I

Solution 1:

Thanks for the answers. What I ended up doing using the: AssetFileDescriptor API to get the file size of the zip file and setting that as the ProgessBar.setMax() value. Then as I loop through the zip contents I increment the progress by using each entries file size. This works but the only concern I have is that the AssetFileDescriptor.getLength() value as well as the ZipEntry.getSize() values return a long value so I am forced to cast them to an integer before I can set the max and/or increment the ProgessBar so there is a slight possibility I might overload an integer value causing an exception but this is not likely because I do not anticipate my file sizes ever getting bigger than the max holding capacity of an integer.

ZipInputStreamzin=newZipInputStream(getAssets().open(
                            "myFile.zip"));
ZipEntryze=null;
AssetFileDescriptormydisc= getAssets().openFd("myFile.zip");
//Size of the zip packagelongsize= mydisc.getLength();
longincrement=0;
dialog.setMax((int) size);
while ((ze = zin.getNextEntry()) != null) {
     increment += (int) ze.getSize();
     progessBar.setProgess((int)increment);
     //do more stuff..
}

Not the best solution but it works.

I'm aware of the ZipFile API but it requires a string to be passed in but I am not sure what the path is to that directory or how to get it?

Solution 2:

Use ZipFile API, There is a size method that returns the number of ZipEntries in the ZipFile. You can read from assets folder.

example:

intzipEntriesCount(String path)throws IOException {

     ZipFile zf= newZipFile(path);
     return zf.size();
}

Solution 3:

Your basic problem seems to be that you have to do progressBar.setMax() before you start reading the file, and you are setting the max based on the number of files.

Have you thought about doing progressBar.setMax(zin.getSize()) and then keeping track of how many bytes you've written when you call progressBar.setProgress(), instead of how many files you've read? This should solve your problem and will give you (imho) a more accurate progress bar.

Solution 4:

this is my solution based on @davorb idea which is to show progress based on file size and not content of zip file.

import android.content.Context;
import android.util.Log;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

publicclassZipUtility {
    privatefinalStringTAG="Decompress";
    private ZipExtractionCallback zipExtractionCallback;

    publicZipUtility(ZipExtractionCallback zipExtractionCallback) {
        this.zipExtractionCallback = zipExtractionCallback;
    }
////    private void unzipFromAssets(Context context, String zipFile, String destination) {//        try {//            if (destination == null || destination.length() == 0)//                destination = context.getFilesDir().getAbsolutePath();//            new File(destination).delete();//            InputStream stream = context.getAssets().open(zipFile);//            unzip(stream, destination);////            SharedPreferenceHelper.Write(context,////                    SharedPreferenceConst.SharedPreferenceName,////                    SharedPreferenceConst.MapExtracted,////                    "1");//        } catch (IOException e) {//            e.printStackTrace();//        }//    }privatebooleandeleteDirectory(String file)/*throws IOException, InterruptedException */ {

        try {
            if (newFile(file).exists()) {
                StringdeleteCommand="rm -rf " + file/*.getAbsolutePath()*/;
                Runtimeruntime= Runtime.getRuntime();
                Processprocess= runtime.exec(deleteCommand);
                process.waitFor();
                returntrue;
            }
        } catch (Exception ignore) {
        }

        returnfalse;
    }

    publicvoidunzipFromPath(Context context, String zipFilePath, String destination) {

        try {
            if (destination == null || destination.length() == 0)
                destination = context.getFilesDir().getAbsolutePath();
            zipExtractionCallback.progress(0, "حذف فایل های قدیمی...");
            deleteDirectory(destination + "html");
            unzip(zipFilePath, destination);
            zipExtractionCallback.progress(0, "حذف فایل اضافی...");
            deleteDirectory(zipFilePath);
        } catch (IOException e) {
            zipExtractionCallback.error("خطا هنگام عملیات استخراج : " + e.getMessage());
            e.printStackTrace();
        }
        zipExtractionCallback.finish();
    }
////    public static void unzip(String zipFile, String location) {//        try {//            FileInputStream fin = new FileInputStream(zipFile);//            unzip(fin, location);//        } catch (FileNotFoundException e) {//            e.printStackTrace();//        }////    }privatevoidunzip(String zipFilePath, String destination)throws IOException {
        longsize=newFile(zipFilePath).length();
        longdecompressedSize=0;
        InputStreamstream=newFileInputStream(newFile(zipFilePath));
        dirChecker(destination, "");
//        int entries = 0;inttotal=0;
        ZipInputStreamzin=newZipInputStream(stream);

//        while ((zin.getNextEntry()) != null) {//            if (entries % 100 == 0)//                zipExtractionCallback.progress(0, "در حال خواندن محتویات:" + entries + " فایل");//            entries++;//        }
        zin.close();
        stream = newFileInputStream(newFile(zipFilePath));
        intp=0;
        longtotalBytes=0;
        intBUFFER_SIZE=1024 * 10;
        byte[] buffer = newbyte[BUFFER_SIZE];
        try {
            zin = newZipInputStream(stream);
            ZipEntryze=null;
            while ((ze = zin.getNextEntry()) != null) {
                decompressedSize += ze.getSize();
                //Log.v(TAG, "Unzipping " + ze.getName());if (ze.isDirectory()) {
                    dirChecker(destination, ze.getName());
                } else {
                    Filef=newFile(destination, ze.getName());
                    if (!f.exists()) {
                        booleansuccess= f.createNewFile();
                        if (!success) {
                            //Log.w(TAG, "Failed to create file " + f.getName());continue;
                        }
                        FileOutputStreamfout=newFileOutputStream(f);
                        //BufferedOutputStream out = new BufferedOutputStream(fout);int count;
                        while ((count = zin.read(buffer)) != -1) {
                            fout.write(buffer, 0, count);
                            //out.write(buffer, 0, count);
                            totalBytes += count;
                        }
                        zin.closeEntry();
                        fout.close();
                    }
                }
//                int progress = 1 + (total++ * 100 / entries);if (size < decompressedSize)
                    size = decompressedSize;
                intprogress= (int) ( (totalBytes * 100L / size));
                if (p < progress)
                    zipExtractionCallback.progress(progress, "در حال استخراج از حالت فشرده:");
                p = progress;
            }
            zin.close();
        } catch (Exception e) {
            zipExtractionCallback.error("خطا هنگام عملیات استخراج : " + e.getMessage());
            Log.e(TAG, "unzip", e);
        }
    }

    privatevoiddirChecker(String destination, String dir) {
        Filef=newFile(destination, dir);

        if (!f.isDirectory()) {
            booleansuccess= f.mkdirs();
            if (!success) {
                Log.w(TAG, "Failed to create folder " + f.getName());
            }
        }
    }


    publicinterfaceZipExtractionCallback {

        voidprogress(int progress, String status);

        voidfinish();

        voiderror(String error);
    }

}

Example of using it :

privatevoidExtractMap(String zipFilePath,Context context) {

    newThread(newRunnable() {
        @Overridepublicvoidrun() {

            ZipUtility zipUtility = newZipUtility(newZipUtility.ZipExtractionCallback() {
                @Overridepublicvoidprogress(int progress, String status) {
                    ((UpdateActivity) context).runOnUiThread(newRunnable() {
                        @Overridepublicvoidrun() {
                             //todo handle ui
                        }
                    });
                }

                @Overridepublicvoidfinish() {

                    ((UpdateActivity) context).runOnUiThread(newRunnable() {
                        @Overridepublicvoidrun() {
                            //todo handle ui
                        }
                    });

                }

                @Overridepublicvoiderror(String error) {
                    ((UpdateActivity) context).runOnUiThread(newRunnable() {
                        @Overridepublicvoidrun() {
                           //todo handle ui
                        }
                    });
                }
            });

            zipUtility.unzipFromPath(context,
                    zipFilePath,
                    context.getFilesDir().getAbsolutePath() + File.separator);


        }
    }).start();
}

Post a Comment for "Android: Get Number Of Files Within Zip?"