Java中可以使用ZipInputStream和GZIPInputStream来解压缩压缩文件,其中ZipInputStream可以处理嵌套的压缩文件。
以下是一个用Java解压缩嵌套的压缩文件的示例代码:
package com.demo.util;
/**
* description:zip解压例子
*
* @author: lgq
* @create: 2023-05-17 18:49
*/
import java.io.*;
import java.util.zip.*;
public class UnzipExample {
public static void unzip(File zipFile, File destination) throws IOException {
byte[] buffer = new byte[1024];
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null) {
File newFile = newFile(destination, zipEntry);
if (zipEntry.isDirectory()) {
if (!newFile.isDirectory() && !newFile.mkdirs()) {
throw new IOException("Failed to create directory " + newFile);
}
} else {
File parent = newFile.getParentFile();
if (!parent.isDirectory() && !parent.mkdirs()) {
throw new IOException("Failed to create directory " + parent);
}
try (FileOutputStream fos = new FileOutputStream(newFile)) {
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
}
try {
zipEntry = zis.getNextEntry(); //有些文件会报错,例如.json文件,不需要处理的话可以直接跳过
} catch (ZipException e) {
zipEntry = zis.getNextEntry();
}
}
}
}
private static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
File destFile = new File(destinationDir, zipEntry.getName());
String destDirPath = destinationDir.getCanonicalPath();
String destFilePath = destFile.getCanonicalPath();
if (!destFilePath.startsWith(destDirPath + File.separator)) {
throw new IOException("Entry is outside of the target directory: " + zipEntry.getName());
}
return destFile;
}
public static void main(String[] args) throws IOException {
File zipFile = new File("D:\\帆软\\treasures.zip");
File destination = new File("D:\\帆软\\unzipped");
unzip(zipFile, destination);
}
}
该示例代码使用了try-with-resources语句来确保关闭流,它还包含了一个newFile()方法,该方法用于检查解压缩文件的目录是否在指定的目标目录中。
如果嵌套的zip文件也需要被解压缩,可以使用递归方法来遍历所有的zip文件并解压缩。以下是一个简单的Java代码示例,可以解压缩所有嵌套的zip文件。
package com.demo.util;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* description:unzipAll例子
*
* @author: lgq
* @create: 2023-05-17 18:58
*/
import java.io.*;
import java.util.Enumeration;
import java.util.zip.*;
public class UnzipAllExample {
public static void main(String[] args) {
String zipFilePath = "D:\\帆软\\treasures.zip";
String destDirPath = "D:\\帆软";
unzipAll(zipFilePath, destDirPath);
}
public static void unzipAll(String zipFilePath, String destDirPath) {
try {
File destDir = new File(destDirPath);
if (!destDir.exists()) {
destDir.mkdir();
}
ZipFile zipFile = new ZipFile(zipFilePath);
ZipEntry entry;
String entryName;
File entryFile, entryDir;
InputStream inStream;
OutputStream outStream;
byte[] buffer = new byte[1024];
int bytesRead;
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
entry = (ZipEntry) e.nextElement();
entryName = entry.getName();
entryFile = new File(destDir, entryName);
if (entry.isDirectory()) {
entryFile.mkdirs();
} else {
entryDir = new File(entryFile.getParent());
if (!entryDir.exists()) {
entryDir.mkdirs();
}
inStream = zipFile.getInputStream(entry);
outStream = new FileOutputStream(entryFile);
while ((bytesRead = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
outStream.close();
inStream.close();
if (entryName.endsWith(".zip")) {
unzipAll(entryFile.getAbsolutePath(), entryDir.getAbsolutePath());
}
//这里也可以做一些需要的文件读取操作
}
}
zipFile.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
在这个示例中,unzipAll
方法接收一个zip文件的路径和一个目标目录的路径,并递归地解压缩所有嵌套的zip文件。如果一个zip文件被解压缩,它将被保存到与其同级的目录中。
你可以将 zipFilePath
和 destDirPath
替换为你自己的实际值,然后运行这个示例来解压缩所有嵌套的zip文件。
参考:ChitGPT