9

I put a zip file in the android assets. How do i extract the file in the android internal storage? I know how to get the file, but i don't know how to extract it. This is my code..

Util zip ;

zip = new Util();

zip.copyFileFromAsset(this, "myfile.zip", getExternalStorage()+ "/android/data/edu.binus.profile/");

Thanks for helping :D

kyuu
  • 237
  • 3
  • 7
  • 15
  • what problem u are getting? where u want to extract zip file inside internal storage or External Storage? – ρяσѕρєя K Mar 26 '13 at 02:41
  • You do know that assets are being zipped by Android tools, anyhow. So you're doing double compression by placing a zip file in there. If you wish to bundle the files together, you might: use tar? do your own zipping without compression? If the bundling is not the goal, just place the files raw and leave compression to Android toolchain. – akauppi Feb 14 '14 at 11:58

5 Answers5

15

This piece of code will help you....Just pass the zipfile location and the location where you want the extracted files to be saved to this class while making an object...and call unzip method...

    public class Decompress { 
  private String zip; 
  private String loc; 

  public Decompress(String zipFile, String location) { 
    zip = zipFile; 
    loc = location; 

    dirChecker(""); 
  } 

  public void unzip() { 
    try  { 
      FileInputStream fin = new FileInputStream(zip); 
      ZipInputStream zin = new ZipInputStream(fin); 
      ZipEntry ze = null; 
      while ((ze = zin.getNextEntry()) != null) { 
        Log.v("Decompress", "Unzipping " + ze.getName()); 

        if(ze.isDirectory()) { 
          dirChecker(ze.getName()); 
        } else { 
          FileOutputStream fout = new FileOutputStream(loc + ze.getName()); 
          for (int c = zin.read(); c != -1; c = zin.read()) { 
            fout.write(c); 
          } 

          zin.closeEntry(); 
          fout.close(); 
        } 

      } 
      zin.close(); 
    } catch(Exception e) { 
      Log.e("Decompress", "unzip", e); 
    } 

  } 

  private void dirChecker(String dir) { 
    File f = new File(_location + dir); 

    if(!f.isDirectory()) { 
      f.mkdirs(); 
    } 
  } 
} 
Sreedev
  • 6,563
  • 5
  • 43
  • 66
  • for (int c = zin.read(); c != -1; c = zin.read()) { fout.write(c); } Time consumption is going on here is there any other way to write on the file in the fast manner – Manmohan Soni Nov 14 '13 at 08:34
  • 12
    @user2260963 The code above reads one byte after another. Try using a buffer that is bigger, e.g. `final int BUFFER = 2048; byte data[] = new byte[BUFFER]; int count; while((count = zin.read(data, 0, BUFFER)) != -1) { fout.write(data, 0, count); }`. – david.schreiber May 28 '14 at 11:45
  • @david.schreiber hey tnx man, dunno why ur comment still not upvoted, it's incrised execution time like 2048 times! – JaLoveAst1k Jun 06 '14 at 13:45
  • @david.schreiber I'm using the class above. My file (eg. filename.xml) is in assets folder of project. Can you please tell me how to make the object of this class. I'm getting File not found exception. – prasang7 Jul 16 '16 at 01:12
  • what is _location? – Vincent Paing Apr 26 '18 at 05:35
  • how to call the class in mainactivity like what to mention in the parameter of unzip() for getting the files from assets folder. – Prajwal Waingankar Sep 10 '19 at 06:06
14

Based on Sreedev R solution, I added the option to read the file from assets and use buffer:

package com.pixoneye.api.utils;

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

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

public class Decompress {
    private static final int BUFFER_SIZE = 1024 * 10;
    private static final String TAG = "Decompress";

    public static void unzipFromAssets(Context context, String zipFile, String destination) {
        try {
            if (destination == null || destination.length() == 0)
                destination = context.getFilesDir().getAbsolutePath();
            InputStream stream = context.getAssets().open(zipFile);
            unzip(stream, destination);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void unzip(String zipFile, String location) {
        try {
            FileInputStream fin = new FileInputStream(zipFile);
            unzip(fin, location);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }

    public static void unzip(InputStream stream, String destination) {
        dirChecker(destination, "");
        byte[] buffer = new byte[BUFFER_SIZE];
        try {
            ZipInputStream zin = new ZipInputStream(stream);
            ZipEntry ze = null;

            while ((ze = zin.getNextEntry()) != null) {
                Log.v(TAG, "Unzipping " + ze.getName());

                if (ze.isDirectory()) {
                    dirChecker(destination, ze.getName());
                } else {
                    File f = new File(destination, ze.getName());
                    if (!f.exists()) {
                        boolean success = f.createNewFile();
                        if (!success) {
                            Log.w(TAG, "Failed to create file " + f.getName());
                            continue;
                        }
                        FileOutputStream fout = new FileOutputStream(f);
                        int count;
                        while ((count = zin.read(buffer)) != -1) {
                            fout.write(buffer, 0, count);
                        }
                        zin.closeEntry();
                        fout.close();
                    }
                }

            }
            zin.close();
        } catch (Exception e) {
            Log.e(TAG, "unzip", e);
        }

    }

    private static void dirChecker(String destination, String dir) {
        File f = new File(destination, dir);

        if (!f.isDirectory()) {
            boolean success = f.mkdirs();
            if (!success) {
                Log.w(TAG, "Failed to create folder " + f.getName());
            }
        }
    }
}
Hank Moody
  • 354
  • 2
  • 15
Asaf Pinhassi
  • 15,177
  • 12
  • 106
  • 130
1

Maybe you should try using a FileOutputStream in combination with an inputstream from the zip file. With a package file, this should work.

To quote @wordy from this question:

PackageManager pm = context.getPackageManager();
String apkFile = pm.getApplicationInfo(context.getPackageName(), 0).sourceDir;
ZipFile zipFile = new ZipFile(apkFile); 
ZipEntry entry = zipFile.getEntry("assets/FILENAME");
myInput = zipFile.getInputStream(entry);
myOutput = new FileOutputStream(file);
    byte[] buffer = new byte[1024*4];
int length;
int total = 0;
int counter = 1;
while ((length = myInput.read(buffer)) > 0) {
    total += length;
    counter++;
    if (counter % 32 == 0) {
        publishProgress(total);
    }
        myOutput.write(buffer, 0, length);
}

Looks like there may be problems with ProGuard but hopefully the code sample works for you.

Community
  • 1
  • 1
Kgrover
  • 2,106
  • 2
  • 36
  • 54
0

I haven't tested yet,but while doing a project on OCR I came across this library,where there is method of unzipping a downloaded file from the net. The exact method for unzipping file is installZipFromAssets(String sourceFilename,File destinationDir,File destinationFile) found under this class.Hope this is what you are looking for

laaptu
  • 2,963
  • 5
  • 30
  • 49
0

You can also make use of the zip4j external library that provides additional features like encryption. Also, it has functions to extract files to a particular location provided the path.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
AndyFaizan
  • 1,833
  • 21
  • 30