Reading files from a ZIP file in your Android asse

2019-01-23 16:04发布

问题:

I'm reading files from a ZIP file that's located in my Android assets folder using ZipInputStream: it works, but it's really slow, as it has to read it sequentially using getNextEntry(), and there are quite a lot of files.

If I copy the ZIP file onto the SD card, reading is really fast when using ZipFile.getEntry, but I didn't find a way to use ZipFile with the asset file!

Is there any way to access the ZIP in the asset folder in a speedy way? Or do I really have to copy the ZIP to the SD card?

(BTW, in case anybody wonders why I'm doing this: the app is larger than 50 MB, so in order to get it in the Play Store I have to use Expansion APKs; however, as this app should also be put into the Amazon App Store, I have to use another version for this, as Amazon doesn't support Expansion APKs, naturally... I thought that accessing a ZIP file at two different locations would be an easy way to handle this, but alas...)

回答1:

This works for me:

private void loadzip(String folder, InputStream inputStream) throws IOException
{
    ZipInputStream zipIs = new ZipInputStream(inputStream); 
    ZipEntry ze = null;

            while ((ze = zipIs.getNextEntry()) != null) {

                FileOutputStream fout = new FileOutputStream(folder +"/"+ ze.getName());

                byte[] buffer = new byte[1024];
                int length = 0;

                while ((length = zipIs.read(buffer))>0) {
                fout.write(buffer, 0, length);
                }
                zipIs.closeEntry();
                fout.close();
            }
            zipIs.close();
}


回答2:

You can store the uncompressed files directly in assets (i.e. unpack the zip into assets/ folder). This way, you can access the files directly and they will be compressed anyway when you build the APK.



回答3:

You can create a ZipInputStream in the following way :

ZipInputStream zipIs = new ZipInputStream(context.getResources().openRawResource(your.package.com.R.raw.filename)); 
ZipEntry ze = null;

        while ((ze = zipIs.getNextEntry()) != null) {

            FileOutputStream fout = new FileOutputStream(FOLDER_NAME +"/"+ ze.getName());

            byte[] buffer = new byte[1024];
            int length = 0;

            while ((length = zipIs.read(buffer))>0) {
            fout.write(buffer, 0, length);
            }
            zipIs .closeEntry();
            fout.close();
        }
        zipIs .close();