You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android执行tar解压文件时部分设备报gunzip Permission denied如何解决

报错原因

  • 你当前解压的是gzip压缩后的tar包(通常后缀为.tar.gz或.tgz),调用系统tar命令使用-xvf参数时,部分版本的tar会自动识别gzip压缩格式,自动fork子进程调用系统内置的gunzip工具完成预解压,报错的本质是你的应用没有执行系统gunzip二进制文件的权限。
  • 该问题仅在少数设备出现,是因为这些设备的厂商定制ROM时修改了系统二进制文件的权限配置,将/system/bin/gunzip的执行权限限制到了特定用户组,普通第三方应用的UID不在允许执行的范围内,所以触发权限拒绝。

可行解决方案

优先推荐方案2,完全不依赖系统工具,不存在版本适配问题。

方案1:拆分解压流程,规避tar自动调用gunzip

先在代码层用内置API完成gzip解压,再调用tar命令解压普通tar包,避免tar内部调用系统gunzip触发权限限制。
示例逻辑:

// 先处理gzip解压生成临时普通tar文件
val gzipIs = GZIPInputStream(FileInputStream(file))
val tempTarFile = File(tempDirectory, "temp_plain.tar")
FileOutputStream(tempTarFile).use { out ->
    gzipIs.copyTo(out)
}
// 再调用tar命令解压无压缩的普通tar包
val untar = arrayOf("tar", "-xvf", tempTarFile.absolutePath, "-C", tempDirectory.absolutePath)
val process = Runtime.getRuntime().exec(untar)
process.waitFor()
// 执行完成后删除临时文件
tempTarFile.delete()

方案2:改用纯Java/Kotlin实现的解压库,完全规避系统工具调用

使用Apache Commons Compress库实现全内置解压,不需要调用任何系统二进制文件,兼容性最高。
首先引入依赖(build.gradle.kts):

dependencies {
    implementation("org.apache.commons:commons-compress:1.24.0")
}

解压逻辑示例:

fun untarGz(sourceFile: File, targetDir: File) {
    targetDir.mkdirs()
    GZIPInputStream(FileInputStream(sourceFile)).use { gzInputStream ->
        TarArchiveInputStream(gzInputStream).use { tarInputStream ->
            var entry: TarArchiveEntry? = tarInputStream.nextTarEntry
            while (entry != null) {
                val outputFile = File(targetDir, entry.name)
                if (entry.isDirectory) {
                    outputFile.mkdirs()
                } else {
                    outputFile.parentFile?.mkdirs()
                    FileOutputStream(outputFile).use { outStream ->
                        tarInputStream.copyTo(outStream)
                    }
                    // 可选:保留原文件的权限配置
                    outputFile.setExecutable(entry.mode and 0b111 != 0)
                    outputFile.setWritable(entry.mode and 0b110 != 0)
                    outputFile.setReadable(entry.mode and 0b100 != 0)
                }
                entry = tarInputStream.nextTarEntry
            }
        }
    }
}

方案3:内置自定义二进制工具到应用私有目录

将编译好的对应ABI架构的tar、gunzip二进制文件放到项目assets目录,运行时拷贝到应用私有目录(/data/data/[你的包名]/files路径下),赋予执行权限后再调用,完全绕过系统二进制的权限限制。

注:该方案需要适配所有目标ABI架构(armeabi-v7a、arm64-v8a、x86等),会少量增加应用包体积。

内容的提问来源于stack exchange,提问作者M Dissi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 16:24:07