Zipping and Unzipping Files in Android

Oğuzhan Aslan
3 min readDec 1, 2023
Photo by JJ Ying on Unsplash

File compression is a critical task for managing large numbers of documents or sending files through the web. However, zipping files is not always as straightforward as it could be. As any developer can attest, simplifying this process can lead to efficiencies and save tremendous amounts of time and frustration. Below, we dive into the intricacies of file compression and decompression using Java’s utility classes in Android.

The Art of Zipping Files in Android

Zipping files involves more work than one might initially assume. Behind the simple action of creating a compressed archive lies a series of steps that the program must carefully execute to avoid errors. Using Java’s built-in utility, ZipOutputStream, along with other associated classes, we can systematically compress multiple files into a single ZIP file.

 fun zip(filesToCompress: List<String>, outputZipFilePath: String) {
val buffer = ByteArray(1024)

try {
val fos = FileOutputStream(outputZipFilePath)
val zos = ZipOutputStream(fos)

filesToCompress.forEach { file ->
val ze = ZipEntry(File(file).name)
zos.putNextEntry(ze)
val `in` = FileInputStream(file)
while(true) {
val len = `in`.read(buffer)
if (len <= 0) break
zos.write(buffer, 0, len)
}

`in`.close()
}

zos.closeEntry()
zos.close()
} catch (e: Exception) {
e.printStackTrace()
}
}

The provided Kotlin-based function handles this elegantly within its zip method. To illustrate, the method initializes a byte buffer which acts as a temporary holding area for data as it’s transferred. For every file listed to compress, it creates a corresponding ZipEntry. This entry is then filled with data read from the source file, and data is written into the ZipOutputStream until all files are processed.

One of the key strengths of this approach is its simplicity and reusability. By iterating over the provided list of file paths, it encapsulates the compression details, so the calling code operates at a higher level of abstraction.

If you go ahead and run the code, you will see a zip file is created in the given output path.

Unzipping Made Easy

Unzipping, by contrast, is relatively easier, albeit not completely without its challenges. The following code provides a unZipmethod, which significantly reduces the complexity of the decompression process. Upon ensuring that the destination directory exists, it processes the ZIP file entry by entry, extracts the appropriate streams, and writes out the uncompressed data.

fun unZip(
zipFilePath: String,
unzipDirectoryPath: String
) {
val unzipDir = File(unzipDirectoryPath)
if (!unzipDir.exists()) {
unzipDir.mkdir()
}

val zipFile = File(zipFilePath)
ZipFile(zipFile).unzip(unzipDir)
}

fun ZipFile.unzip(
unzipDir: File
) {
val enum = entries()
while (enum.hasMoreElements()) {
val entry = enum.nextElement()
val entryName = entry.name
val fis = FileInputStream(this.name)
val zis = ZipInputStream(fis)

while (true) {
val nextEntry = zis.nextEntry ?: break
if (nextEntry.name == entryName) {
val fout = FileOutputStream(File(unzipDir, nextEntry.name))
var c = zis.read()
while (c != -1) {
fout.write(c)
c = zis.read()
}
zis.closeEntry()
fout.close()
}
}

zis.close()
}
}

The key here is the iteration over ZipFile entries and careful handling of streams, ensuring we do not miss any files while unzipping. Again, the ZipFacade encapsulates the nitty-gritty details so that we do not have to manage the lower-level file I/O operations explicitly every time we want to extract a set of files.

Disclaimer: The code shared in this blog is for educational and illustrative purposes only and should be thoroughly tested before using in a production environment.

Sample Project

Conclusion

In conclusion, file compression and decompression don’t have to be daunting tasks. By utilizing Java’s ZipOutputStream and other utility classes, we can create robust zipping and unzipping functionalities that handle the heavy lifting behind the scenes. With the ZipFacade object at your disposal, you can easily integrate file zipping and unzipping into your Java or Kotlin projects, saving both time and resources.

--

--