Java解压带密码7z文件遇‘Bad 7z signature’错误求解决
解决Java解压带密码7z文件时的"Bad 7z signature"错误
排查方向与修复步骤:
先确认7z文件的有效性
手动用官方7-Zip工具打开目标文件,验证文件是否未损坏、密码是否正确。如果工具都无法打开,问题出在文件本身,和代码无关。修正密码编码方式
7z规范要求密码以UTF-16LE无BOM编码转换为字节数组,Java中"UTF16"编码默认会带BOM,这会导致密码不匹配。替换成StandardCharsets.UTF_16LE来获取正确的字节数组:byte[] pass = password.getBytes(StandardCharsets.UTF_16LE);清理代码中的无效/错误逻辑
- 你代码中读取整个文件到
inputData但未使用,这部分冗余代码可以直接删除,避免不必要的内存占用。 - 代码中出现未定义的
wb变量(wb.write(fileOut);和wb.close();),属于语法错误,会导致运行异常,直接删除这两行。
- 你代码中读取整个文件到
确保依赖库版本兼容
确认使用的Apache Commons Compress版本是最新稳定版(比如1.24.0+),旧版本对加密7z的支持可能存在缺陷。
修正后的完整代码:
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry; import org.apache.commons.compress.archivers.sevenz.SevenZFile; import java.io.*; import java.nio.charset.StandardCharsets; public void unpack7z(String directory, String encryptCompressFileName, String password) { SevenZFile sevenZFile = null; SevenZArchiveEntry entry = null; try { File file = new File(directory + File.separator + encryptCompressFileName); // 初始化SevenZFile if (password != null && !password.isEmpty()) { byte[] passBytes = password.getBytes(StandardCharsets.UTF_16LE); sevenZFile = new SevenZFile(file, passBytes); } else { sevenZFile = new SevenZFile(file); } // 遍历所有条目 while ((entry = sevenZFile.getNextEntry()) != null) { String processingFileName = entry.getName(); if (entry.isDirectory()) { System.out.printf("Found directory entry: %s%n", processingFileName); // 创建目录(避免路径不存在导致写入失败) new File(directory + File.separator + processingFileName).mkdirs(); } else { System.out.printf("Unpacking start: %s ...%n", processingFileName); ByteArrayOutputStream contentBytes = new ByteArrayOutputStream(); byte[] buffer = new byte[2048]; int bytesRead; while ((bytesRead = sevenZFile.read(buffer)) != -1) { contentBytes.write(buffer, 0, bytesRead); } // 写入文件到目标路径 File outputFile = new File(directory + File.separator + processingFileName); // 确保父目录存在 outputFile.getParentFile().mkdirs(); try (FileOutputStream fileOut = new FileOutputStream(outputFile)) { fileOut.write(contentBytes.toByteArray()); fileOut.flush(); } System.out.printf("Unpacking finish: %s ...%n", processingFileName); } } } catch (Exception e) { e.printStackTrace(); } finally { if (sevenZFile != null) { try { sevenZFile.close(); } catch (IOException e) { e.printStackTrace(); } } } }
额外提示:拼接文件路径时建议用File.separator替代硬编码的斜杠,保证跨平台兼容性;同时要创建目标文件的父目录,避免因路径不存在导致写入失败。
内容的提问来源于stack exchange,提问作者Pintu
相关产品推荐
相关产品推荐

