本文目录导读:

Java中实现压缩文件解压,最常用的就是 Zip 格式,Java标准库中的 java.util.zip 包提供了原生支持,对于 RAR 格式,Java标准库不支持,需要借助第三方库(如 Apache Commons Compress 或 junrar)。
下面我为你提供 Java 解压 Zip 和 RAR 文件的核心案例代码。
解压 Zip 文件 (Java原生实现)
这是最常用且无需引入任何第三方依赖的方法。
import java.io.*;
import java.nio.charset.Charset;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipDecompressor {
/**
* 解压ZIP文件
* @param zipFilePath 要解压的zip文件路径
* @param destDirPath 解压到目标目录的路径
* @param charset 编码格式 (中文文件名建议使用 GBK 或 UTF-8)
* @throws IOException 如果发生I/O错误
*/
public static void unzip(String zipFilePath, String destDirPath, Charset charset) throws IOException {
File destDir = new File(destDirPath);
// 如果目标目录不存在,则创建
if (!destDir.exists()) {
destDir.mkdirs();
}
// 使用 ZipInputStream 读取文件 (推荐处理大文件)
try (ZipInputStream zis = new ZipInputStream(
new FileInputStream(zipFilePath), charset)) {
ZipEntry entry;
byte[] buffer = new byte[1024];
// 遍历zip内的每一个条目
while ((entry = zis.getNextEntry()) != null) {
// 构建目标文件路径 (注意防止路径穿越漏洞)
File newFile = new File(destDir, entry.getName());
String destDirCanonical = destDir.getCanonicalPath();
String newFileCanonical = newFile.getCanonicalPath();
// 安全检查:防止压缩包内包含 ".." 导致的路径穿越
if (!newFileCanonical.startsWith(destDirCanonical + File.separator)) {
throw new IOException("Entry is outside of the target dir: " + entry.getName());
}
if (entry.isDirectory()) {
// 如果是目录,创建目录
newFile.mkdirs();
} else {
// 如果是文件,确保父目录存在
newFile.getParentFile().mkdirs();
// 写入文件内容
try (FileOutputStream fos = new FileOutputStream(newFile)) {
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
}
zis.closeEntry(); // 关闭当前条目
}
}
}
// 简便方法 (默认UTF-8编码)
public static void unzip(String zipFilePath, String destDirPath) throws IOException {
unzip(zipFilePath, destDirPath, Charset.forName("UTF-8"));
}
// 测试示例
public static void main(String[] args) {
try {
String zipFile = "D:/test/example.zip";
String destDir = "D:/test/output/";
// 尝试UTF-8 (Linux/Mac) 或 GBK (Windows中文系统)
try {
unzip(zipFile, destDir, Charset.forName("UTF-8"));
} catch (Exception e) {
System.out.println("UTF-8解压失败,尝试GBK...");
unzip(zipFile, destDir, Charset.forName("GBK"));
}
System.out.println("解压完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
代码要点说明:
- 路径穿越防护:
ZipSlip漏洞是解压时常见的安全问题,恶意压缩包可能包含 文件名覆盖其他文件。 - 编码问题:Windows上很多压缩软件使用GBK编码,Linux/Mac使用UTF-8,建议先尝试UTF-8,失败再尝试GBK。
ZipInputStream:适合大文件,流式读取,不会把所有文件加载到内存。
解压 RAR 文件 (使用 Apache Commons Compress)
RAR是专有格式,Java标准库不支持,推荐使用 org.apache.commons.compress。
Maven依赖 (pom.xml):
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.26.2</version> <!-- 请使用最新稳定版 -->
</dependency>
代码示例:
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.rar.RarArchiveInputStream;
import org.apache.commons.compress.utils.IOUtils;
import java.io.*;
public class RarDecompressor {
public static void unrar(String rarFilePath, String destDirPath) throws Exception {
File destDir = new File(destDirPath);
if (!destDir.exists()) {
destDir.mkdirs();
}
// 创建解压输入流
try (ArchiveInputStream ais = new ArchiveStreamFactory()
.createArchiveInputStream(ArchiveStreamFactory.RAR,
new BufferedInputStream(new FileInputStream(rarFilePath)))) {
ArchiveEntry entry;
while ((entry = ais.getNextEntry()) != null) {
// 构建目标文件路径 (同样需要路径穿越防护)
File newFile = new File(destDir, entry.getName());
String destDirCanonical = destDir.getCanonicalPath();
String newFileCanonical = newFile.getCanonicalPath();
if (!newFileCanonical.startsWith(destDirCanonical + File.separator)) {
throw new IOException("Entry is outside of the target dir: " + entry.getName());
}
if (entry.isDirectory()) {
newFile.mkdirs();
} else {
newFile.getParentFile().mkdirs();
// 使用Commons Compress提供的IOUtils简化写入
try (OutputStream os = new FileOutputStream(newFile)) {
IOUtils.copy(ais, os);
}
}
}
}
}
// 测试示例
public static void main(String[] args) {
try {
unrar("D:/test/example.rar", "D:/test/output_rar/");
System.out.println("RAR解压完成!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:
RarArchiveInputStream目前只能解压 RAR v3 格式,对于 RAR v5 格式,commons-compress的纯Java实现支持有限,可能需要使用junrar或调用系统unrar命令行。
解压常见问题的总结与建议
| 文件格式 | 推荐方案 | 注意事项 |
|---|---|---|
| .zip | 标准库 java.util.zip |
注意编码(GBK/UTF-8);注意路径穿越漏洞 |
| .tar.gz / .tar.bz2 | Apache Commons Compress | TarArchiveInputStream + GzipCompressorInputStream |
| .7z | Apache Commons Compress (需额外依赖 xz 或 lzma) |
依赖于 org.tukaani:xz 库 |
| .rar | Apache Commons Compress / junrar | RAR v4支持较好,RAR v5可能需用命令行 |
性能建议:
- 对于超大文件 (如几百MB以上的ZIP),使用
ZipInputStream流式处理,避免使用ZipFile一次性加载条目索引。 - 对于多文件压缩包,可以考虑使用多线程解压不同文件(注意线程安全,每个文件单独输出流)。
如果你有具体的文件格式或特殊场景(如加密的ZIP、分卷压缩),欢迎进一步提问,我可以给出更针对性的方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播