How to zip directories & files on Android using Kotlin

eye catch Android

How to zip directories & files in Android

Android has ZipFile class as a standard API.

Quote : ZipFile | Android Developers

This class is used to read entries from a zip file.Unless otherwise noted, passing a null argument to a constructor or method in this class will cause a NullPointerException to be thrown.

https://developer.android.com/reference/kotlin/java/util/zip/ZipFile

Examples of the use of ZipFile are presented in this article.

1. Create ZipUtils class for reusability

Here I’ve created a ZipUtils class to increase the reusability of the ZipFile.

Sample code – ZipUtils.kt

object ZipUtils {

    private val TAG = ZipUtils::class.java.simpleName

    fun zipFiles(zipOut: ZipOutputStream, sourceDir: File, parentDirPath: String) {
        val data = ByteArray(2048)
        for (f in sourceDir.listFiles()) {
            if (f.isDirectory) {
                val path = f.name + File.separator
                val entry = ZipEntry(path)
                entry.time = f.lastModified()
                entry.size = f.length()
                entry.isDirectory
                Log.i(TAG, "Adding Dir : ${path}")
                zipOut.putNextEntry(entry)
                zipFiles(zipOut, f, f.name)
            } else {
                if (!f.name.contains(".zip")) { //If folder contains a file with extension ".zip", skip it
                    FileInputStream(f).use { fi ->
                        BufferedInputStream(fi).use { origin ->
                            val path = parentDirPath + File.separator + f.name
                            Log.i("zip", "Adding file: $path")
                            val entry = ZipEntry(path)
                            entry.time = f.lastModified()
                            entry.size = f.length()
                            entry.isDirectory
                            zipOut.putNextEntry(entry)
                            while (true) {
                                val readBytes = origin.read(data)
                                if (readBytes == -1) { break }
                                zipOut.write(data, 0, readBytes)
                            }
                        }
                    }
                } else {
                    zipOut.closeEntry()
                    zipOut.close()
                }
            }
        }
    }
}

The sourceDir is the root directory File which you wish to zip.

From that starting point, files and folders can be compressed recursively as a single zip.

2. Let a user create zip file

Then write the code to have the user create a zip file.

Sample code in Activity class :

/// Target directory to be compressed
val targetDir = File("/path/to/target")

/// ActivityResultLauncher
val createZipLauncher = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
){ result ->
    
    val outStream = contentResolver.openOutputStream(result.data?.data!!)
    ZipOutputStream(BufferedOutputStream(outStream)).use {
        it.use {
            /// Compress destDir and write it to new created zip file.
            ZipUtils.zipFiles(it, targetDir, "")
        }
    }
}

/// Open file picker for creating Zip file
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
intent.setType("application/zip")
createZipLauncher.launch(intent)

We’ve successfully created a zip file!

You need not to find any library 🙂

There is no need to search Github for a library for Zip.

ZipFile has everything you need to read or write a zip.

1 thought on “How to zip directories & files on Android using Kotlin

Leave a Reply