Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of How to zip folder and sub-folder using zip4j and outputstream without wasting too much if your time.
The question is published on by Tutorial Guruji team.
The question is published on by Tutorial Guruji team.
In the program that I am writing, I take the uri of the location to save the zip file from a user. Then, I try to zip the files and folders using zip4j library and outpustream in Android. I modified the code in this Stackoverflow answer and used zip4j instead. My modified code produces the zip file, however it is corrupted.
this is my code written in Kotlin:
class ZipBuilder { private fun buildZipParameters(compressionMethod: CompressionMethod, compressionLevel: CompressionLevel, encrypt: Boolean, encryptionMethod: EncryptionMethod?, aesKeyStrength: AesKeyStrength? ): ZipParameters? { val zipParameters = ZipParameters() zipParameters.compressionMethod = compressionMethod zipParameters.compressionLevel = compressionLevel return zipParameters } fun zipFileAtPath(sourcePath: String?, toLocation: ParcelFileDescriptor?): Boolean { println("zipFileAtPath is called") val BUFFER = 2048 val sourceFile = File(sourcePath!!) val zipParameters = buildZipParameters(CompressionMethod.DEFLATE, CompressionLevel.NORMAL, false, null, null) try { var origin: BufferedInputStream? = null val desc = toLocation val dest = FileOutputStream(desc!!.fileDescriptor) val out = ZipOutputStream(BufferedOutputStream(dest)) if (sourceFile.isDirectory) { zipParameters.rootFolderNameInZip = sourcePath zipSubFolder(out, sourceFile, sourceFile.parent!!.length, zipParameters!!) } else { val data = ByteArray(BUFFER) val fi = FileInputStream(sourcePath) origin = BufferedInputStream(fi, BUFFER) zipParameters!!.fileNameInZip = getLastPathComponent(sourcePath) zipParameters.lastModifiedFileTime = sourceFile.lastModified() out.putNextEntry(zipParameters) var count: Int = 0 while (fi.read(data).also({ count = it }) != -1) { out.write(data, 0, count) } } out.close() } catch (e: java.lang.Exception) { e.printStackTrace() return false } return true } @Throws(IOException::class) private fun zipSubFolder( out: ZipOutputStream, folder: File, basePathLength: Int, zipParameters: ZipParameters ) { val BUFFER = 2048 val fileList = folder.listFiles() var origin: BufferedInputStream fileList?.forEach { file -> if (file.isDirectory) { zipSubFolder(out, file, basePathLength, zipParameters) } else { val data = ByteArray(BUFFER) val unmodifiedFilePath = file.path val relativePath = unmodifiedFilePath .substring(basePathLength) val fi = FileInputStream(unmodifiedFilePath) origin = BufferedInputStream(fi, BUFFER) zipParameters.fileNameInZip = relativePath zipParameters.lastModifiedFileTime = file.lastModified() out.putNextEntry(zipParameters) var count: Int = 0 while (fi.read(data).also({ count = it }) != -1) { out.write(data, 0, count) } origin.close() } } } fun getLastPathComponent(filePath: String): String? { val segments = filePath.split("/").toTypedArray() return if (segments.size == 0) "" else segments[segments.size - 1] } }
I would appreciate it if someone could tell me what could be the problem.
Answer
I guess you forgot to closeEntry()
after writing date for that particular entry. You need to do out.closeEntry()
after the while loop of writing data. Have a look at the example here.
while (fi.read(data).also({ count = it }) != -1) { out.write(data, 0, count) } out.closeEntry() // --> close entry after writing data
We are here to answer your question about How to zip folder and sub-folder using zip4j and outputstream - If you find the proper solution, please don't forgot to share this with your team members.