问题
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 want to display to the user how the progress is going.
I have everything working but I want to set the ProgessBar
max value to be the number of files within the zip file. The number of files within this folder will sometimes change so I want the ProgessBar
to be relative to how many files are contained within the zip.
I'm using the ZipInputStream
-API but does not seem there is a way to get the number of files within the zip file. The only way I can of think of is doing this:
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);
}
This works but having two while loops seems a bit redundant which are basically doing the same thing.
I know that there is a ZipFile
-API which has a size()
-method, but it requires a path to the file and since my file is located within the 'assets' folder I am pretty sure the only way to read from this directory is by streaming.
Is there a way for me to accomplish this?
回答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.
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..
}
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?
回答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:
int zipEntriesCount(String path) throws IOException {
ZipFile zf= new ZipFile(path);
return zf.size();
}
回答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.
来源:https://stackoverflow.com/questions/6795389/android-get-number-of-files-within-zip