在kotlin中使用Apache Commons Compress和协程解压带密码的7z文件

并发有错误,待改正.

依赖

dependencies{
    // https://mvnrepository.com/artifact/org.apache.commons/commons-compress
    implementation("org.apache.commons:commons-compress:1.21")
    // https://mvnrepository.com/artifact/org.tukaani/xz
    implementation("org.tukaani:xz:1.9")
    // https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0-RC2")
}

实现

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.apache.commons.compress.archivers.sevenz.SevenZFile
import java.io.File
import java.io.IOException

fun main(args: Array<String>): Unit = runBlocking {
    //args[0]是7z文件,args[1]是密码,args[2]是解压目录.三个参数都不能带空格
    val sevenZFile = SevenZFile(File(args[0]), args[1].toCharArray())
    val targetDir = File(args[2]).md()
    sevenZFile.decompressTo2(targetDir)

}

//保证有此目录
fun File.md() = this.apply {
    if (!isDirectory && !mkdirs()) throw IOException("failed to create directory $absolutePath")
}

//解压
suspend fun SevenZFile.decompressTo(targetDir: File) = withContext(Dispatchers.IO) {
    targetDir.md()
    for (entry in entries) {
        launch(Dispatchers.IO) {
            // 每个项目的绝对路径
            val entryPath = "${targetDir.absolutePath}/${entry.name}"
            // 如果是一个目录
            if (entry?.isDirectory == true) {
                // 创建该目录
                File(entryPath).md()
            } else {
                //是文件
                println("正在解压 ${entry.name}")
                //创建该文件的父目录
                File(entryPath).parentFile.md()
                //解压文件
                this@decompressTo.getInputStream(entry).copyTo(File(entryPath).outputStream())
            }
        }
    }
}

posted @ 2021-12-15 01:56  SoClear  阅读(596)  评论(0编辑  收藏  举报