【发布时间】:2020-09-14 17:09:28
【问题描述】:
有没有一种方法可以在 Java 中解压缩带有各种子文件夹的 ZIP 文件,而无需安装任何额外的插件。
例如,我想用这个代码解压缩文件https://services.gradle.org/distributions/gradle-6.4.1-bin.zip:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class unzipfile {
private static void unzip(String zipFilePath, String zipFileName, String destDir) {
System.out.print("Extracting " + zipFileName + "...");
File dir = new File(destDir);
// create output directory if it doesn't exist
if(!dir.exists()) dir.mkdirs();
FileInputStream fis;
//buffer for read and write data to file
byte[] buffer = new byte[1024];
try {
fis = new FileInputStream(zipFilePath);
try (ZipInputStream zis = new ZipInputStream(fis)) {
ZipEntry ze = zis.getNextEntry();
while(ze != null){
String fileName = ze.getName();
File newFile = new File(destDir + File.separator + fileName);
//create directories for sub directories in zip
new File(newFile.getParent()).mkdirs();
try (FileOutputStream fos = new FileOutputStream(newFile)) {
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
//close this ZipEntry
ze = zis.getNextEntry();
}
}
fis.close();
System.out.println(" Done!");
} catch (IOException e) {
System.out.println(" Error while extracting " + zipFileName);
Logger.getLogger(unzipfile.class.getName()).log(Level.SEVERE, null, e);
}
}
public static void main(String[] args) {
try{
unzip(args[0], args[1], args[2]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("No valid arguments specified. Usage:\n");
System.out.println("\'java unzipfile [ZIP file path with file name] [file name only] [target directory]\'");
System.exit(1);
}
}
}
我跑:
java unzipfile path\to\file\gradle-6.4.1-bin.zip gradle-6.4.1-bin.zip .
但是当我运行完整的应用程序时,它会给我以下信息:
Extracting gradle-6.4.1-bin.zip... Error while extracting gradle-6.4.1-bin.zip
may. 27, 2020 5:44:37 P.áM. unzipfile unzip
SEVERE: null
java.io.FileNotFoundException: .\gradle-6.4.1\README (El sistema no puede encontrar la ruta especificada)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:291)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:234)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:184)
at unzipfile.unzip(unzipfile.java:29)
at unzipfile.main(unzipfile.java:50)
感谢您的宝贵时间。
【问题讨论】:
-
至少打印来自
IOException的消息,最好是整个堆栈跟踪。如果不这样做,您实际上是在丢弃有用的调试信息。 -
我不这样做是因为我想将此程序与另一个下载文件的程序集成,因此错误日志会很烦人。
-
仅供参考: 1) 您无需致电
zis.closeEntry(),因此您可以删除这两行代码。 --- 2) 您使用 try-with-resources,但随后拥有fis独立?坏的! --- 3) 使用更新的 NIO.2 API 代替旧的 File I/O API。错误消息要好得多(假设您实际显示它们)。 -
请修复代码中非常糟糕的缩进。阅读起来非常困难,但不会误读。
-
@Lumito: 1. 即使您稍后删除它,您现在也可以添加它来调试您的问题 2. 在库中调用
System.exit()比 更烦人日志行,因为调用者永远无法解决这个问题...... 3. 如果发生解压缩问题,您打算如何向调用者报告?当出现问题时,您的方法应该有明确定义的行为。