我查看了JDK和Apache压缩库附带的默认Zip库,我对它们不满意,原因有3个:
They are bloated and have bad API design. I have to write 50 lines of boiler plate byte array output, zip input, file out streams and close relevant streams and catch exceptions and move byte buffers on my own? Why can't I have a simple API that looks like this Zipper.unzip(InputStream zipFile, File targetDirectory, String password = null) and Zipper.zip(File targetDirectory, String password = null) that just works?
It seems zipping unzipping destroys file meta-data and password handling is broken.
Also, all the libraries I tried were 2-3x slow compared to the command line zip tools I get with UNIX?
对我来说(2)和(3)是次要的点,但我真的想要一个良好的测试库与一行接口。
在Java 8中,使用Apache Commons-IO的IOUtils你可以这样做:
try (java.util.zip.ZipFile zipFile = new ZipFile(file)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
File entryDestination = new File(outputDir, entry.getName());
if (entry.isDirectory()) {
entryDestination.mkdirs();
} else {
entryDestination.getParentFile().mkdirs();
try (InputStream in = zipFile.getInputStream(entry);
OutputStream out = new FileOutputStream(entryDestination)) {
IOUtils.copy(in, out);
}
}
}
}
它仍然是一些样板代码,但它只有一个非外来依赖项:Commons-IO
在Java 11及更高版本中,可能会有更好的选择,请参阅ZhekaKozlov的评论。
我知道有点晚了,有很多答案,但这个zip4j是我使用过的最好的压缩库之一。它很简单(没有锅炉代码),可以很容易地处理密码保护文件。
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.core.ZipFile;
public static void unzip(){
String source = "some/compressed/file.zip";
String destination = "some/destination/folder";
String password = "password";
try {
ZipFile zipFile = new ZipFile(source);
if (zipFile.isEncrypted()) {
zipFile.setPassword(password);
}
zipFile.extractAll(destination);
} catch (ZipException e) {
e.printStackTrace();
}
}
Maven依赖项是:
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>