kotlin中使用zip 压缩和解压

使用操作系统工具进行压缩和解压,总会出现意料之外的问题,例如 mac 上的__MAXOS的文件夹,windows中的中文文件名的编码问题,所以这类压缩文件最好使用代码去操作。

代码如下,测试时,可以使用build文件夹辅助测试


class ZipUtil {
    val TAG = "ZipUtil"

    @Test
    fun testZipFile() {
        val f1 = File("./build/ziptest/中文.txt")
        createFile(f1.path)
        val f2 = File("./build/ziptest/2.txt")
        createFile(f2.path)
        val f3 = File("./build/ziptest/3.txt")
        createFile(f3.path)

        zip(listOf(f1, f2, f3), "./build/ziptest.zip")

        val res = "./build/zipresult"
        unzip("./build/ziptest.zip", res)
        Assert.assertEquals(3, File(res).listFiles().size)
    }

    @Test
    fun mp3Zip() {
        val files = File("./build/douyin_music").listFiles().toList()
        zip(files, "./build/douyin.zip")

        unzip("./build/douyin.zip", "./build/douyin_res")

        Assert.assertEquals(files.size, File("./build/douyin_res").listFiles().size)
    }

    /**
     * https://www.jianshu.com/p/2adf4a4b1bd8
     */
    fun unzip(zipFile: String, descDir: String) {
        val buffer = ByteArray(1024)
        var outputStream: OutputStream? = null
        var inputStream: InputStream? = null
        try {
            val zf = ZipFile(zipFile)
            val entries = zf.entries()
            while (entries.hasMoreElements()) {
                val zipEntry: ZipEntry = entries.nextElement() as ZipEntry
                val zipEntryName: String = zipEntry.name

                inputStream = zf.getInputStream(zipEntry)
                val descFilePath: String = descDir + File.separator + zipEntryName
                val descFile: File = createFile(descFilePath)
                outputStream = FileOutputStream(descFile)

                var len: Int
                while (inputStream.read(buffer).also { len = it } > 0) {
                    outputStream.write(buffer, 0, len)
                }
                inputStream.closeQuietly()
                outputStream.closeQuietly()
            }
        } finally {
            inputStream?.closeQuietly()
            outputStream?.closeQuietly()
        }
    }

    private fun createFile(filePath: String): File {
        val file = File(filePath)
        val parentFile = file.parentFile!!
        if (!parentFile.exists()) {
            parentFile.mkdirs()
        }
        if (!file.exists()) {
            file.createNewFile()
        }
        return file
    }

    fun zip(files: List, zipFilePath: String) {
        if (files.isEmpty()) return

        val zipFile = createFile(zipFilePath)
        val buffer = ByteArray(1024)
        var zipOutputStream: ZipOutputStream? = null
        var inputStream: FileInputStream? = null
        try {
            zipOutputStream = ZipOutputStream(FileOutputStream(zipFile))
            for (file in files) {
                if (!file.exists()) continue
                zipOutputStream.putNextEntry(ZipEntry(file.name))
                inputStream = FileInputStream(file)
                var len: Int
                while (inputStream.read(buffer).also { len = it } > 0) {
                    zipOutputStream.write(buffer, 0, len)
                }
                zipOutputStream.closeEntry()
            }
        } finally {
            inputStream?.close()
            zipOutputStream?.close()
        }
    }

    fun zipByFolder(fileDir: String, zipFilePath: String) {
        val folder = File(fileDir)
        if (folder.exists() && folder.isDirectory) {
            val files = folder.listFiles()
            val filesList: List = files.toList()
            zip(filesList, zipFilePath)
        }
    }
}

你可能感兴趣的:(kotlin中使用zip 压缩和解压)