How to unzip files programmatically in Android?
Asked Answered
P

16

150

I need a small code snippet which unzips a few files from a given .zip file and gives the separate files according to the format they were in the zipped file. Please post your knowledge and help me out.

Placet answered 1/8, 2010 at 17:26 Comment(1)
You can get the Kotlin solution here - https://mcmap.net/q/160340/-unzip-a-zipped-file-on-sd-card-in-android-applicationBitty
S
155

Had peno's version optimised a bit. The increase in performance is perceptible.

private boolean unpackZip(String path, String zipname)
{       
     InputStream is;
     ZipInputStream zis;
     try 
     {
         String filename;
         is = new FileInputStream(path + zipname);
         zis = new ZipInputStream(new BufferedInputStream(is));          
         ZipEntry ze;
         byte[] buffer = new byte[1024];
         int count;

         while ((ze = zis.getNextEntry()) != null) 
         {
             filename = ze.getName();

             // Need to create directories if not exists, or
             // it will generate an Exception...
             if (ze.isDirectory()) {
                File fmd = new File(path + filename);
                fmd.mkdirs();
                continue;
             }

             FileOutputStream fout = new FileOutputStream(path + filename);

             while ((count = zis.read(buffer)) != -1) 
             {
                 fout.write(buffer, 0, count);             
             }

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

         zis.close();
     } 
     catch(IOException e)
     {
         e.printStackTrace();
         return false;
     }

    return true;
}
Seringapatam answered 12/6, 2012 at 13:37 Comment(13)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />Influential
do you think same code works for unzipping or unpacking the expansion APK Expansion Files obb files?Disinterested
I think yes, it works, because it is very usual way of unpacking things. Just manage to get the right 'path' and 'zipname'. I've also seen some stuff you might be interested in (sure you've seen it already though): linkSeringapatam
Because you need to skip the "file-only" operations if your ze is a directory. Trying to perform these operations will cause an exception.Seringapatam
Why don't you make that method static? Would it work?Shadrach
This is amazing. Previously I have used the same ZipInputStream but different solution and it took 140 seconds to unzip 2MB file. Now it in real time, thanks!!Joeyjoffre
Nice speed "drugs" doping method, but is correct this awesome speed ?Iconoscope
Will this work on folders or only files? And if not, then how do I unzip folders?Nellynelms
This answer should not work, because it doesn't create the missing files to write data on it !!Athamas
Actually, this code won't work if the zip file is create without junk path, for example, you can run this code to unzip an APK file, you will get FileNotFoundException.Duwalt
I agree with @Duwalt . If the zip was created without directory entries, it will not work. Each file should be checked if the directory it is supposed to be extracted to exists. zip -j will not generate directory entries. EDIT: actually didn't notice, but the next answer from zapi is the right one.Staffordshire
Please note, as stated by @Shaw: if your ZIP file does not contain explicit folders, such method will fail with FileNotFoundException since it's missing a "new File(path + File.separator + filename).getParentFile().mkdirs()" in the !isDirectory() branchEffluent
Wouldn't using BufferedOutputStream(FileOutputStream) be faster than using the FileOutputStream itself?Hower
C
112

Based on Vasily Sochinsky's answer a bit tweaked & with a small fix:

public static void unzip(File zipFile, File targetDirectory) throws IOException {
    ZipInputStream zis = new ZipInputStream(
            new BufferedInputStream(new FileInputStream(zipFile)));
    try {
        ZipEntry ze;
        int count;
        byte[] buffer = new byte[8192];
        while ((ze = zis.getNextEntry()) != null) {
            File file = new File(targetDirectory, ze.getName());
            File dir = ze.isDirectory() ? file : file.getParentFile();
            if (!dir.isDirectory() && !dir.mkdirs())
                throw new FileNotFoundException("Failed to ensure directory: " +
                        dir.getAbsolutePath());
            if (ze.isDirectory())
                continue;
            FileOutputStream fout = new FileOutputStream(file);
            try {
                while ((count = zis.read(buffer)) != -1)
                    fout.write(buffer, 0, count);
            } finally {
                fout.close();
            }
            /* if time should be restored as well
            long time = ze.getTime();
            if (time > 0)
                file.setLastModified(time);
            */
        }
    } finally {
        zis.close();
    }
}

Notable differences

  • public static - this is a static utility method that can be anywhere.
  • 2 File parameters because String are :/ for files and one could not specify where the zip file is to be extracted before. Also path + filename concatenation > https://mcmap.net/q/80290/-how-to-combine-paths-in-java
  • throws - because catch late - add a try catch if really not interested in them.
  • actually makes sure that the required directories exist in all cases. Not every zip contains all the required directory entries in advance of file entries. This had 2 potential bugs:
    • if the zip contains an empty directory and instead of the resulting directory there is an existing file, this was ignored. The return value of mkdirs() is important.
    • could crash on zip files that don't contain directories.
  • increased write buffer size, this should improve performance a bit. Storage is usually in 4k blocks and writing in smaller chunks is usually slower than necessary.
  • uses the magic of finally to prevent resource leaks.

So

unzip(new File("/sdcard/pictures.zip"), new File("/sdcard"));

should do the equivalent of the original

unpackZip("/sdcard/", "pictures.zip")
Costar answered 20/11, 2014 at 22:18 Comment(11)
hello i m getting path with backward slash like sdcard/temp/768\769.json so i am getting error can u tell me how to manage itAcadian
@AndoMasahashi that should be a legal filename on a linux filesystem. What error do you get and how should the filename look like at the end?Costar
it look like /sdcard/pictures\picturess.jpeg and error file not found errorAcadian
It works fine, but it throws exception when one of the file name inside zip is not in UTF8 format. So, I used this code instead which uses apache's commons-compress lib.Wuhsien
@AshishTanna indeed, it's a known Problem blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_inCostar
Hii,I had this, what is this and how to solve this one, please help me, java.util.zip.ZipException: CRC mismatchApprentice
@Vijaykumar your zip is probably corrupt. Maybe like in #11059139 you download it the wrong way. Or maybe you just put a broken zip file. Get the file off of the device and check that it works with a desktop unzip tool.Costar
@Vijaykumar The comment section is a bad place to ask much / debug. Please post a new question showing how you the zip file comes to the device. Maybe linking to the actual file so people can reproduce your error. "CRC error" means the checksum of the extracted file does not match what the zip file says it should be, therefore something in the zipped data is usually wrong. Meaning you need to look at the file and what happens to it before it hits above code.Costar
Is there a way to check that the user has enough space on their device to unzip the file? What happens currently if they don't?Parasitic
So in the above code, the pictures.zip is stored under the sdcard folder. And when we unzip it, it will be stored within the same sdcard folder? Or outside of sdcard folder? I wanted that my zip location of file and unzip location should be the same! Will that work? If yes, will it wont cause a crash since in the same folder my zip file will also be present.Hourglass
you might want to replace the ZipInputStream object creation/close() with a try-with-resource creation. It's a bit cleaner for a Closeable object. Same for FileOutputStream.Lannie
B
26

This is my unzip method, which I use:

private boolean unpackZip(String path, String zipname)
{       
     InputStream is;
     ZipInputStream zis;
     try 
     {
         is = new FileInputStream(path + zipname);
         zis = new ZipInputStream(new BufferedInputStream(is));          
         ZipEntry ze;

         while((ze = zis.getNextEntry()) != null) 
         {
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
             byte[] buffer = new byte[1024];
             int count;

             String filename = ze.getName();
             FileOutputStream fout = new FileOutputStream(path + filename);

             // reading and writing
             while((count = zis.read(buffer)) != -1) 
             {
                 baos.write(buffer, 0, count);
                 byte[] bytes = baos.toByteArray();
                 fout.write(bytes);             
                 baos.reset();
             }

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

         zis.close();
     } 
     catch(IOException e)
     {
         e.printStackTrace();
         return false;
     }

    return true;
}
Bozo answered 14/9, 2011 at 17:47 Comment(1)
do you think same code works for unzipping or unpacking the expansion APK Expansion Files obb files?Disinterested
B
22

The Kotlin way

//FileExt.kt

data class ZipIO (val entry: ZipEntry, val output: File)

fun File.unzip(unzipLocationRoot: File? = null) {

    val rootFolder = unzipLocationRoot ?: File(parentFile.absolutePath + File.separator + nameWithoutExtension)
    if (!rootFolder.exists()) {
       rootFolder.mkdirs()
    }

    ZipFile(this).use { zip ->
        zip
        .entries()
        .asSequence()
        .map {
            val outputFile = File(rootFolder.absolutePath + File.separator + it.name)
            ZipIO(it, outputFile)
        }
        .map {
            it.output.parentFile?.run{
                if (!exists()) mkdirs()
            }
            it
        }
        .filter { !it.entry.isDirectory }
        .forEach { (entry, output) ->
            zip.getInputStream(entry).use { input ->
                output.outputStream().use { output ->
                    input.copyTo(output)
                }
            }
        }
    }

}

Usage

val zipFile = File("path_to_your_zip_file")
file.unzip()
Bitty answered 22/6, 2018 at 15:7 Comment(2)
It throws an exception at 'output.outputStream() ' line that says "FileNotFoundException ... (Not a directory)"Loincloth
good example, thaks! Works greatCyanamide
C
13

Android has build-in Java API. Check out java.util.zip package.

The class ZipInputStream is what you should look into. Read ZipEntry from the ZipInputStream and dump it into filesystem/folder. Check similar example to compress into zip file.

Copalm answered 1/8, 2010 at 17:32 Comment(2)
You should have provided a code example. You missed out on a lot of points.Hyder
Will it work for 7zip also?Gregson
C
8

use the following class

    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipInputStream;
    import android.util.Log;

    public class DecompressFast {



 private String _zipFile; 
  private String _location; 
 
  public DecompressFast(String zipFile, String location) { 
    _zipFile = zipFile; 
    _location = location; 
 
    _dirChecker(""); 
  } 
 
  public void unzip() { 
    try  { 
      FileInputStream fin = new FileInputStream(_zipFile); 
      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(_location + ze.getName()); 
         BufferedOutputStream bufout = new BufferedOutputStream(fout);
          byte[] buffer = new byte[1024];
          int read = 0;
          while ((read = zin.read(buffer)) != -1) {
              bufout.write(buffer, 0, read);
          }

          
          
          
          bufout.close();
          
          zin.closeEntry(); 
          fout.close(); 
        } 
         
      } 
      zin.close(); 
      
      
      Log.d("Unzip", "Unzipping complete. path :  " +_location );
    } catch(Exception e) { 
      Log.e("Decompress", "unzip", e); 
      
      Log.d("Unzip", "Unzipping failed");
    } 
 
  } 
 
  private void _dirChecker(String dir) { 
    File f = new File(_location + dir); 
 
    if(!f.isDirectory()) { 
      f.mkdirs(); 
    } 
  } 


 }

How to use

 String zipFile = Environment.getExternalStorageDirectory() + "/the_raven.zip"; //your zip file location
    String unzipLocation = Environment.getExternalStorageDirectory() + "/unzippedtestNew/"; // destination folder location
  DecompressFast df= new DecompressFast(zipFile, unzipLocation);
    df.unzip();

Permissions

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Cothran answered 19/10, 2016 at 8:22 Comment(1)
can see the file name, but when trying to extrace the file, i am getting FileNotFoundException errorSilverts
C
7

While the answers that are already here work well, I found that they were slightly slower than I had hoped for. Instead I used zip4j, which I think is the best solution because of its speed. It also allowed for different options for the amount of compression, which I found useful.

Celin answered 23/5, 2013 at 6:7 Comment(0)
C
5

According to @zapl answer,Unzip with progress report:

public interface UnzipFile_Progress
{
    void Progress(int percent, String FileName);
}

// unzip(new File("/sdcard/pictures.zip"), new File("/sdcard"));
public static void UnzipFile(File zipFile, File targetDirectory, UnzipFile_Progress progress) throws IOException,
        FileNotFoundException
{
    long total_len = zipFile.length();
    long total_installed_len = 0;

    ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile)));
    try
    {
        ZipEntry ze;
        int count;
        byte[] buffer = new byte[1024];
        while ((ze = zis.getNextEntry()) != null)
        {
            if (progress != null)
            {
                total_installed_len += ze.getCompressedSize();
                String file_name = ze.getName();
                int percent = (int)(total_installed_len * 100 / total_len);
                progress.Progress(percent, file_name);
            }

            File file = new File(targetDirectory, ze.getName());
            File dir = ze.isDirectory() ? file : file.getParentFile();
            if (!dir.isDirectory() && !dir.mkdirs())
                throw new FileNotFoundException("Failed to ensure directory: " + dir.getAbsolutePath());
            if (ze.isDirectory())
                continue;
            FileOutputStream fout = new FileOutputStream(file);
            try
            {
                while ((count = zis.read(buffer)) != -1)
                    fout.write(buffer, 0, count);
            } finally
            {
                fout.close();
            }

            // if time should be restored as well
            long time = ze.getTime();
            if (time > 0)
                file.setLastModified(time);
        }
    } finally
    {
        zis.close();
    }
}
Colchis answered 5/1, 2015 at 9:54 Comment(0)
F
3
public class MainActivity extends Activity {

private String LOG_TAG = MainActivity.class.getSimpleName();

private File zipFile;
private File destination;

private TextView status;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    status = (TextView) findViewById(R.id.main_status);
    status.setGravity(Gravity.CENTER);

    if ( initialize() ) {
        zipFile = new File(destination, "BlueBoxnew.zip");
        try {
            Unzipper.unzip(zipFile, destination);
            status.setText("Extracted to \n"+destination.getAbsolutePath());
        } catch (ZipException e) {
            Log.e(LOG_TAG, e.getMessage());
        } catch (IOException e) {
            Log.e(LOG_TAG, e.getMessage());
        }
    } else {
        status.setText("Unable to initialize sd card.");
    }
}

public boolean initialize() {
    boolean result = false;
     File sdCard = new File(Environment.getExternalStorageDirectory()+"/zip/");
    //File sdCard = Environment.getExternalStorageDirectory();
    if ( sdCard != null ) {
        destination = sdCard;
        if ( !destination.exists() ) {
            if ( destination.mkdir() ) {
                result = true;
            }
        } else {
            result = true;
        }
    }

    return result;
}

 }

->Helper Class(Unzipper.java)

    import java.io.File;
    import java.io.FileInputStream;
   import java.io.FileOutputStream;
    import java.io.IOException;
       import java.util.zip.ZipEntry;
    import java.util.zip.ZipException;
    import java.util.zip.ZipInputStream;
     import android.util.Log;

   public class Unzipper {

private static String LOG_TAG = Unzipper.class.getSimpleName();

public static void unzip(final File file, final File destination) throws ZipException, IOException {
    new Thread() {
        public void run() {
            long START_TIME = System.currentTimeMillis();
            long FINISH_TIME = 0;
            long ELAPSED_TIME = 0;
            try {
                ZipInputStream zin = new ZipInputStream(new FileInputStream(file));
                String workingDir = destination.getAbsolutePath()+"/";

                byte buffer[] = new byte[4096];
                int bytesRead;
                ZipEntry entry = null;
                while ((entry = zin.getNextEntry()) != null) {
                    if (entry.isDirectory()) {
                        File dir = new File(workingDir, entry.getName());
                        if (!dir.exists()) {
                            dir.mkdir();
                        }
                        Log.i(LOG_TAG, "[DIR] "+entry.getName());
                    } else {
                        FileOutputStream fos = new FileOutputStream(workingDir + entry.getName());
                        while ((bytesRead = zin.read(buffer)) != -1) {
                            fos.write(buffer, 0, bytesRead);
                        }
                        fos.close();
                        Log.i(LOG_TAG, "[FILE] "+entry.getName());
                    }
                }
                zin.close();

                FINISH_TIME = System.currentTimeMillis();
                ELAPSED_TIME = FINISH_TIME - START_TIME;
                Log.i(LOG_TAG, "COMPLETED in "+(ELAPSED_TIME/1000)+" seconds.");
            } catch (Exception e) {
                Log.e(LOG_TAG, "FAILED");
            }
        };
    }.start();
}

   }

->xml layout(activity_main.xml):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context=".MainActivity" >

<TextView
    android:id="@+id/main_status"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:text="@string/hello_world" />

</RelativeLayout>

->permission in Menifest file:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Feliks answered 3/9, 2013 at 6:16 Comment(0)
J
2

Here is a ZipFileIterator (like a java Iterator, but for zip files):

package ch.epfl.bbp.io;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZipFileIterator implements Iterator<File> {

    private byte[] buffer = new byte[1024];

    private FileInputStream is;
    private ZipInputStream zis;
    private ZipEntry ze;

    public ZipFileIterator(File file) throws FileNotFoundException {
    is = new FileInputStream(file);
    zis = new ZipInputStream(new BufferedInputStream(is));
    }

    @Override
    public boolean hasNext() {
    try {
        return (ze = zis.getNextEntry()) != null;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
    }

    @Override
    public File next() {
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int count;

        String filename = ze.getName();
        File tmpFile = File.createTempFile(filename, "tmp");
        tmpFile.deleteOnExit();// TODO make it configurable
        FileOutputStream fout = new FileOutputStream(tmpFile);

        while ((count = zis.read(buffer)) != -1) {
        baos.write(buffer, 0, count);
        byte[] bytes = baos.toByteArray();
        fout.write(bytes);
        baos.reset();
        }
        fout.close();
        zis.closeEntry();

        return tmpFile;

    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    }

    @Override
    public void remove() {
    throw new RuntimeException("not implemented");
    }

    public void close() {
    try {
        zis.close();
        is.close();
    } catch (IOException e) {// nope
    }
    }
}
Jointworm answered 4/6, 2012 at 10:3 Comment(1)
do you think same code works for unzipping or unpacking the expansion APK Expansion Files obb files?Disinterested
T
2

Minimal example I used to unzip a specific file from my zipfile into my applications cache folder. I then read the manifest file using a different method.

private void unzipUpdateToCache() {
    ZipInputStream zipIs = new ZipInputStream(context.getResources().openRawResource(R.raw.update));
    ZipEntry ze = null;

    try {

        while ((ze = zipIs.getNextEntry()) != null) {
            if (ze.getName().equals("update/manifest.json")) {
                FileOutputStream fout = new FileOutputStream(context.getCacheDir().getAbsolutePath() + "/manifest.json");

                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();

    } catch (IOException e) {
        e.printStackTrace();
    }

}
Teahan answered 13/3, 2017 at 7:27 Comment(0)
A
2

I'm working with zip files which Java's ZipFile class isn't able to handle. Java 8 apparently can't handle compression method 12 (bzip2 I believe). After trying a number of methods including zip4j (which also fails with these particular files due to another issue), I had success with Apache's commons-compress which supports additional compression methods as mentioned here.

Note that the ZipFile class below is not the one from java.util.zip.

It's actually org.apache.commons.compress.archivers.zip.ZipFile so be careful with the imports.

try (ZipFile zipFile = new ZipFile(archiveFile)) {
    Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
    while (entries.hasMoreElements()) {
        ZipArchiveEntry entry = entries.nextElement();
        File entryDestination = new File(destination, entry.getName());
        if (entry.isDirectory()) {
            entryDestination.mkdirs();
        } else {
            entryDestination.getParentFile().mkdirs();
            try (InputStream in = zipFile.getInputStream(entry); OutputStream out = new FileOutputStream(entryDestination)) {
                IOUtils.copy(in, out);
            }
        }
    }
} catch (IOException ex) {
    log.debug("Error unzipping archive file: " + archiveFile, ex);
}

For Gradle:

compile 'org.apache.commons:commons-compress:1.18'
Affluent answered 26/8, 2018 at 7:15 Comment(0)
P
2

Based on zapl's answer, adding try() around Closeable's closes the streams automatically after use.

public static void unzip(File zipFile, File targetDirectory) {
    try (FileInputStream fis = new FileInputStream(zipFile)) {
        try (BufferedInputStream bis = new BufferedInputStream(fis)) {
            try (ZipInputStream zis = new ZipInputStream(bis)) {
                ZipEntry ze;
                int count;
                byte[] buffer = new byte[Constant.DefaultBufferSize];
                while ((ze = zis.getNextEntry()) != null) {
                    File file = new File(targetDirectory, ze.getName());
                    File dir = ze.isDirectory() ? file : file.getParentFile();
                    if (!dir.isDirectory() && !dir.mkdirs())
                        throw new FileNotFoundException("Failed to ensure directory: " + dir.getAbsolutePath());
                    if (ze.isDirectory())
                        continue;
                    try (FileOutputStream fout = new FileOutputStream(file)) {
                        while ((count = zis.read(buffer)) != -1)
                            fout.write(buffer, 0, count);
                    }
                }
            }
        }
    } catch (Exception ex) {
        //handle exception
    }
}

Using Constant.DefaultBufferSize (65536) gotten from C# .NET 4 Stream.CopyTo from Jon Skeet's answer here: https://mcmap.net/q/53524/-how-do-i-save-a-stream-to-a-file-in-c

I always just see posts using byte[1024] or byte[4096] buffer, never knew it can be much larger which improves performance and is still working perfectly normal.

Here is the Stream Source code: https://referencesource.microsoft.com/#mscorlib/system/io/stream.cs

//We pick a value that is the largest multiple of 4096 that is still smaller than the large object heap threshold (85K).
// The CopyTo/CopyToAsync buffer is short-lived and is likely to be collected at Gen0, and it offers a significant
// improvement in Copy performance.

private const int _DefaultCopyBufferSize = 81920;

However, I dialed it back to 65536 which is also a multiple of 4096 just to be safe.

Petrolic answered 31/10, 2019 at 6:3 Comment(1)
This is best solution in this thread. In addition, I would also use BufferedOutputStream in stack with FileOutputStream.Furman
H
1

Password Protected Zip File

if you want to compress files with password you can take a look at this library that can zip files with password easily:

Zip:

ZipArchive zipArchive = new ZipArchive();
zipArchive.zip(targetPath,destinationPath,password);

Unzip:

ZipArchive zipArchive = new ZipArchive();
zipArchive.unzip(targetPath,destinationPath,password);

Rar:

RarArchive rarArchive = new RarArchive();
rarArchive.extractArchive(file archive, file destination);

The documentation of this library is good enough, I just added a few examples from there. It's totally free and wrote specially for android.

Henriquez answered 7/11, 2017 at 9:37 Comment(0)
S
0

Here is more concise version of @arsent solution:

fun File.unzip(to: File? = null) {
    val destinationDir = to ?: File(parentFile, nameWithoutExtension)
    destinationDir.mkdirs()

    ZipFile(this).use { zipFile ->
        zipFile
            .entries()
            .asSequence()
            .filter { !it.isDirectory }
            .forEach { zipEntry ->
                val currFile = File(destinationDir, zipEntry.name)
                currFile.parentFile?.mkdirs()
                zipFile.getInputStream(zipEntry).use { input ->
                    currFile.outputStream().use { output -> input.copyTo(output) }
                }
            }
    }
}
Seiter answered 17/11, 2021 at 14:13 Comment(0)
K
0

In Kotlin, this Function can be helpful :

if this path is a internal storage, don't need any permission.

For example

val file = File(context.getDir("Music", AppCompatActivity.MODE_PRIVATE),
                        "/$myFilename$myExtensionVar")

unpackZipFile(file.path,"zipFileName")

otherwise add permission for read/write external storage.

 private fun unpackZipFile(path: String, zipFileName: String): Boolean {
        val `is`: InputStream
        val zis: ZipInputStream
        try {
            var filename: String
            // Here put the Zip file path
            `is` = FileInputStream(path+zipFileName)
            zis = ZipInputStream(BufferedInputStream(`is`))
            var ze: ZipEntry
            val buffer = ByteArray(1024)
            var count: Int
            
            while (zis.nextEntry.also { ze = it } != null) {
                filename = ze.name
                
                if (ze.isDirectory) {
                    val fmd = File(path+ filename )
                    fmd.mkdirs()
                    continue
                }
                val fileOutputStream = FileOutputStream(path +filename )
                while (zis.read(buffer).also { count = it } != -1) {
                    fileOutputStream.write(buffer, 0, count)
                }
                fileOutputStream.close()
                zis.closeEntry()
            }
            zis.close()



        } catch (e: IOException) {
            e.printStackTrace()
            return false
        }catch (e:NullPointerException){
            e.printStackTrace()
            return false
        }
        return true
    }
Kure answered 17/4, 2023 at 6:55 Comment(2)
give me for java code plsTynes
Hi, @Dimas Lanjaka did you try the below codes such as Manohar ? His code in JavaKure

© 2022 - 2024 — McMap. All rights reserved.