本文目录导读:

我将为您提供几个Java操作ZIP文件的完整案例,涵盖压缩、解压、加密等常见场景。
基础ZIP压缩和解压
1 压缩文件/文件夹为ZIP
import java.io.*;
import java.nio.file.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipCompressor {
/**
* 压缩文件或文件夹
* @param sourcePath 源文件/文件夹路径
* @param zipPath 目标ZIP文件路径
*/
public static void compress(String sourcePath, String zipPath) throws IOException {
File sourceFile = new File(sourcePath);
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipPath))) {
compressFile(sourceFile, sourceFile.getName(), zos);
}
}
private static void compressFile(File file, String fileName, ZipOutputStream zos)
throws IOException {
if (file.isDirectory()) {
// 创建目录条目
if (!fileName.endsWith("/")) {
fileName += "/";
}
zos.putNextEntry(new ZipEntry(fileName));
zos.closeEntry();
// 递归处理子文件和子目录
File[] files = file.listFiles();
if (files != null) {
for (File childFile : files) {
compressFile(childFile, fileName + childFile.getName(), zos);
}
}
} else {
// 创建文件条目
zos.putNextEntry(new ZipEntry(fileName));
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
}
zos.closeEntry();
}
}
public static void main(String[] args) {
try {
compress("D:/test/folder", "D:/test/output.zip");
System.out.println("压缩完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
2 解压ZIP文件
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipExtractor {
/**
* 解压ZIP文件
* @param zipPath ZIP文件路径
* @param destDir 目标目录
*/
public static void extract(String zipPath, String destDir) throws IOException {
File destFile = new File(destDir);
if (!destFile.exists()) {
destFile.mkdirs();
}
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipPath))) {
ZipEntry entry;
byte[] buffer = new byte[1024];
while ((entry = zis.getNextEntry()) != null) {
String entryName = entry.getName();
File newFile = new File(destDir + File.separator + entryName);
// 防止路径穿越
String canonicalPath = newFile.getCanonicalPath();
if (!canonicalPath.startsWith(destFile.getCanonicalPath())) {
throw new IOException("非法路径: " + entryName);
}
if (entry.isDirectory()) {
// 创建目录
newFile.mkdirs();
} else {
// 创建父目录
new File(newFile.getParent()).mkdirs();
// 写入文件内容
try (FileOutputStream fos = new FileOutputStream(newFile)) {
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
}
zis.closeEntry();
}
}
}
public static void main(String[] args) {
try {
extract("D:/test/output.zip", "D:/test/unzip");
System.out.println("解压完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用Apache Commons Compress库
1 添加Maven依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.24.0</version>
</dependency>
2 高级压缩功能
import org.apache.commons.compress.archivers.zip.*;
import org.apache.commons.compress.parallel.InputStreamSupplier;
import java.io.*;
import java.nio.file.*;
import java.util.zip.*;
public class AdvancedZipCompressor {
/**
* 使用自动检测的压缩方法压缩
*/
public static void compressWithBestMethod(String sourcePath, String zipPath)
throws IOException {
try (ZipArchiveOutputStream zos = new ZipArchiveOutputStream(new FileOutputStream(zipPath))) {
zos.setUseZip64(Zip64Mode.AsNeeded);
File source = new File(sourcePath);
compressRecursively(source, source.getName(), zos);
}
}
private static void compressRecursively(File file, String entryName,
ZipArchiveOutputStream zos) throws IOException {
if (file.isDirectory()) {
// 创建目录条目
ZipArchiveEntry dirEntry = new ZipArchiveEntry(entryName + "/");
dirEntry.setMethod(ZipArchiveEntry.STORED);
zos.putArchiveEntry(dirEntry);
zos.closeArchiveEntry();
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
compressRecursively(child, entryName + "/" + child.getName(), zos);
}
}
} else {
ZipArchiveEntry fileEntry = new ZipArchiveEntry(entryName);
// 根据文件大小决定压缩方法
FileInputStream fis = new FileInputStream(file);
try {
if (file.length() > 1024 * 1024) { // 大于1MB使用DEFLATED
fileEntry.setMethod(ZipArchiveEntry.DEFLATED);
} else {
fileEntry.setMethod(ZipArchiveEntry.STORED);
}
zos.putArchiveEntry(fileEntry);
byte[] buffer = new byte[8192];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
} finally {
fis.close();
zos.closeArchiveEntry();
}
}
}
/**
* 提取ZIP文件并保留权限信息
*/
public static void extractWithPermissions(String zipPath, String destDir)
throws IOException {
Path destPath = Paths.get(destDir).toAbsolutePath();
Files.createDirectories(destPath);
try (ZipFile zipFile = new ZipFile(new File(zipPath))) {
zipFile.getEntries().asIterator().forEachRemaining(entry -> {
try {
Path outputPath = destPath.resolve(entry.getName()).normalize();
// 安全检查
if (!outputPath.startsWith(destPath)) {
throw new IOException("非法路径: " + entry.getName());
}
if (entry.isDirectory()) {
Files.createDirectories(outputPath);
} else {
Files.createDirectories(outputPath.getParent());
try (InputStream is = zipFile.getInputStream(entry)) {
Files.copy(is, outputPath, StandardCopyOption.REPLACE_EXISTING);
}
// 设置文件权限
if (entry.getUnixMode() != 0) {
Files.setPosixFilePermissions(outputPath,
convertUnixMode(entry.getUnixMode()));
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}
private static java.util.Set<java.nio.file.attribute.PosixFilePermission>
convertUnixMode(int mode) {
java.util.Set<java.nio.file.attribute.PosixFilePermission> perms =
new java.util.HashSet<>();
if ((mode & 0400) != 0) perms.add(java.nio.file.attribute.PosixFilePermission.OWNER_READ);
if ((mode & 0200) != 0) perms.add(java.nio.file.attribute.PosixFilePermission.OWNER_WRITE);
if ((mode & 0100) != 0) perms.add(java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE);
if ((mode & 0040) != 0) perms.add(java.nio.file.attribute.PosixFilePermission.GROUP_READ);
if ((mode & 0020) != 0) perms.add(java.nio.file.attribute.PosixFilePermission.GROUP_WRITE);
if ((mode & 0010) != 0) perms.add(java.nio.file.attribute.PosixFilePermission.GROUP_EXECUTE);
if ((mode & 0004) != 0) perms.add(java.nio.file.attribute.PosixFilePermission.OTHERS_READ);
if ((mode & 0002) != 0) perms.add(java.nio.file.attribute.PosixFilePermission.OTHERS_WRITE);
if ((mode & 0001) != 0) perms.add(java.nio.file.attribute.PosixFilePermission.OTHERS_EXECUTE);
return perms;
}
}
加密ZIP文件
1 使用Zip4j库(支持AES加密)
添加依赖:
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.11.5</version>
</dependency>
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.*;
import java.io.File;
import java.util.List;
public class EncryptedZipExample {
/**
* 创建加密ZIP文件
*/
public static void createEncryptedZip(String sourcePath, String zipPath,
String password) throws Exception {
ZipParameters zipParameters = new ZipParameters();
// 设置加密
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD_VARIANT_STRONG);
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
// 设置压缩
zipParameters.setCompressionMethod(CompressionMethod.DEFLATE);
zipParameters.setCompressionLevel(CompressionLevel.NORMAL);
ZipFile zipFile = new ZipFile(zipPath, password.toCharArray());
zipFile.setCharset(java.nio.charset.StandardCharsets.UTF_8);
File source = new File(sourcePath);
if (source.isDirectory()) {
zipFile.addFolder(source, zipParameters);
} else {
zipFile.addFile(source, zipParameters);
}
}
/**
* 解密并解压ZIP文件
*/
public static void decryptAndExtract(String zipPath, String password,
String destPath) throws Exception {
ZipFile zipFile = new ZipFile(zipPath, password.toCharArray());
// 验证密码
if (!zipFile.isValidZipFile()) {
throw new Exception("无效的ZIP文件");
}
if (zipFile.isEncrypted()) {
// 尝试测试文件是否可读
if (!zipFile.isValidZipFile()) {
throw new Exception("密码错误或文件损坏");
}
}
zipFile.extractAll(destPath);
}
/**
* 添加文件到现有加密ZIP
*/
public static void addFileToEncryptedZip(String zipPath, String password,
File fileToAdd) throws Exception {
ZipFile zipFile = new ZipFile(zipPath, password.toCharArray());
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
zipFile.addFile(fileToAdd, zipParameters);
}
/**
* 从加密ZIP中获取文件列表
*/
public static List<net.lingala.zip4j.model.FileHeader> getFileList(
String zipPath, String password) throws Exception {
ZipFile zipFile = new ZipFile(zipPath, password.toCharArray());
return zipFile.getFileHeaders();
}
}
2 使用示例
public class ZipExample {
public static void main(String[] args) {
try {
// 1. 基础压缩
ZipCompressor.compress("D:/test/documents", "D:/test/documents.zip");
// 2. 基础解压
ZipExtractor.extract("D:/test/documents.zip", "D:/test/extracted");
// 3. 高级压缩
AdvancedZipCompressor.compressWithBestMethod(
"D:/test/documents", "D:/test/advanced.zip");
// 4. 加密压缩
EncryptedZipExample.createEncryptedZip(
"D:/test/documents", "D:/test/encrypted.zip", "myPassword123");
// 5. 解密并解压
EncryptedZipExample.decryptAndExtract(
"D:/test/encrypted.zip", "myPassword123", "D:/test/decrypted");
System.out.println("所有操作完成!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
实用工具类
import java.io.*;
import java.nio.file.*;
import java.util.zip.*;
public class ZipUtils {
/**
* 压缩单个文件
*/
public static void compressSingleFile(String sourceFile, String zipFile)
throws IOException {
File file = new File(sourceFile);
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {
zos.putNextEntry(new ZipEntry(file.getName()));
Files.copy(file.toPath(), zos);
zos.closeEntry();
}
}
/**
* 压缩内存中的内容为ZIP
*/
public static byte[] compressToBytes(Map<String, byte[]> files)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
for (Map.Entry<String, byte[]> entry : files.entrySet()) {
zos.putNextEntry(new ZipEntry(entry.getKey()));
zos.write(entry.getValue());
zos.closeEntry();
}
}
return baos.toByteArray();
}
/**
* 从ZIP中读取特定文件
*/
public static byte[] extractFile(String zipPath, String fileName)
throws IOException {
try (ZipFile zipFile = new ZipFile(zipPath)) {
ZipEntry entry = zipFile.getEntry(fileName);
if (entry == null) {
throw new FileNotFoundException("文件不存在: " + fileName);
}
try (InputStream is = zipFile.getInputStream(entry)) {
return is.readAllBytes();
}
}
}
/**
* 检查ZIP文件是否有效
*/
public static boolean isValidZip(String zipPath) {
try (ZipFile zipFile = new ZipFile(zipPath)) {
// 尝试读取中央目录
zipFile.size();
return true;
} catch (IOException e) {
return false;
}
}
/**
* 获取ZIP文件中的所有条目名称
*/
public static List<String> listEntries(String zipPath) throws IOException {
List<String> entries = new ArrayList<>();
try (ZipFile zipFile = new ZipFile(zipPath)) {
zipFile.stream().forEach(entry -> entries.add(entry.getName()));
}
return entries;
}
/**
* 删除ZIP中的指定文件
*/
public static void removeFileFromZip(String zipPath, String fileName)
throws IOException {
Path tempFile = Files.createTempFile("zip", ".tmp");
try (ZipFile originalZip = new ZipFile(zipPath);
ZipOutputStream zos = new ZipOutputStream(
new FileOutputStream(tempFile.toFile()))) {
byte[] buffer = new byte[1024];
originalZip.stream()
.filter(entry -> !entry.getName().equals(fileName))
.forEach(entry -> {
try {
zos.putNextEntry(new ZipEntry(entry.getName()));
try (InputStream is = originalZip.getInputStream(entry)) {
int len;
while ((len = is.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
}
zos.closeEntry();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
Files.move(tempFile, Paths.get(zipPath),
StandardCopyOption.REPLACE_EXISTING);
}
}
这些示例涵盖了大多数常见的ZIP操作需求,根据您的具体使用场景,可以选择合适的方法,如果需要更多特定功能的实现,请告诉我具体需求。