Corrupt Zip file using ZipOutputStream to create DOCX file

73 views Asked by At

I use ZipOutputStream to compress the content of a folder into a Zip file. Below is my working code. But it creates corrupt DOCX files. Trying to extract them on macOS fails.

private const val DEFAULT_BUFFER_SIZE = 1024 * 4

fun zip(source: String?, destination: String?, contentsOnly: Boolean, compression: Int) {
    try {
        val zipOut = ZipOutputStream(FileOutputStream(destination))
        val srcFile = File(source)

        // Compression Level
        val compressionLevel: Int = when(compression) {
             0 -> Deflater.DEFAULT_COMPRESSION
             1 -> Deflater.NO_COMPRESSION
             2 -> Deflater.BEST_SPEED
             3 -> Deflater.BEST_COMPRESSION
            else -> {
                Deflater.DEFAULT_COMPRESSION
            }
        }

        zipOut.setLevel(compressionLevel)
        zipOut.setMethod(ZipOutputStream.DEFLATED)

        if (contentsOnly && srcFile.isDirectory) {
            for (fileName in srcFile.list()) {
                addToZip("", source + File.separator + fileName, zipOut)
            }
        } else {
            if (source != null) {
                addToZip("", source, zipOut)
            }
        }
        zipOut.flush()
        zipOut.finish()
        zipOut.close()
        println("Successfully created $destination")
    } catch (error: Exception) {
        println("Failed")
    }
}

private fun addToZip(path: String, srcFile: String, zipOut: ZipOutputStream) {
    val file = File(srcFile)
    val filePath = if ("" == path) file.name else path + File.separator + file.name
    if (file.isDirectory) {
        for (fileName in file.list()) {
            addToZip(filePath, srcFile + File.separator + fileName, zipOut)
        }
    } else {
        zipOut.putNextEntry(ZipEntry(filePath))
        val `in` = FileInputStream(srcFile)
        val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
        var len: Int
        while (`in`.read(buffer).also { len = it } != -1) {
            zipOut.write(buffer, 0, len)
        }
    }
}

I use the code e.g. to compress the folder "paragraph", which you can find here: https://github.com/stiv-yakovenko/toptal-docx/tree/master/paragraph. The Zip file is generated, I can view the Structure inside Android Studio, but if I try to extract it, I get the message the file is corrupt. Compress other folders, which are not based on OfficeOpenXml (.docx, .xsxl etc.) works fine.

0

There are 0 answers