Apache Commons Compress
和 Java 自带的 java.util.zip
包
这两个是原始操作ZipFile的类,灵活性比较高
Zip4j
专门处理ZIP文件的Java库
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.11.5</version>
</dependency>
//创建一个zip文件或者在已有zip文件加文件
new ZipFile("filename.zip").addFile("filename.ext");
new ZipFile("filename.zip").addFile(new File("filename.ext"));
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
//创建一个需要密码的压缩文件
ZipFile zipFile = new ZipFile("filename.zip", "password".toCharArray());
//添加文件夹
new ZipFile("filename.zip").addFolder(new File("/users/some_user/folder_to_add"));
//压缩文件夹时过滤实现ExcludeFileFilter 接口的文件,ZipParameters是默认的压缩配置
ExcludeFileFilter excludeFileFilter = filesToExclude::contains;
ZipParameters zipParameters = new ZipParameters();
zipParameters.setExcludeFileFilter(excludeFileFilter);
new ZipFile("filename.zip").addFolder(new File("/users/some_user/folder_to_add"), zipParameters);
//拿到文件流压缩
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
//加密算法配置
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
// Below line is optional. AES 256 is used by default. You can override it to use AES 128. AES 192 is supported only for extracting.
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
//zip文件分割
ZipFile zipFile = new ZipFile("filename.zip");
zipFile.createSplitZipFile(filesToAdd, new ZipParameters(), true, 10485760); // using 10MB in this example
ps: zip文件格式指定分割文件最小长度65536bytes 指定值小于该值会报错
//解压所有文件,带密码文件,单个文件,单个文件夹
new ZipFile("filename.zip").extractAll("/destination_directory");
new ZipFile("filename.zip", "password".toCharArray()).extractAll("/destination_directory");
new ZipFile("filename.zip").extractFile("fileNameInZip.txt", "/destination_directory");
new ZipFile("filename.zip").extractFile("folderNameInZip/", "/destination_directory");
new ZipFile("filename.zip", "password".toCharArray()).extractFile("fileNameInZip.txt", "/destination_directory");
//解压指定文件到指定文件目录后重新命名
new ZipFile("filename.zip", "password".toCharArray()).extractFile("fileNameInZip.txt", "/destination_directory", "newfileName.txt");
//获取zip文件中某个文件文件输入流
ZipFile zipFile = new ZipFile("filename.zip");
FileHeader fileHeader = zipFile.getFileHeader("entry_name_in_zip.txt");
InputStream inputStream = zipFile.getInputStream(fileHeader);
//移除zip文件中某个文件
new ZipFile("filename.zip").removeFile("fileNameInZipToRemove");
ZipFile zipFile = new ZipFile("someZip.zip");
FileHeader fileHeader = zipFile.getFileHeader("fileNameInZipToRemove");
if (fileHeader == null) {
// file does not exist
}
zipFile.removeFile(fileHeader);
//移除多个文件
ZipFile zipFile = new ZipFile("someZip.zip");
List<String> filesToRemove = Arrays.asList("file1.txt", "file2.txt", "some-folder/", "some-new-folder-1/somefile.pdf");
zipFile.removeFiles(filesToRemove);
//重新命名zip文件中某个文件
ZipFile zipFile = new ZipFile("sample.zip");
FileHeader fileHeader = zipFile.getFileHeader("entry-to-be-changed.pdf");
zipFile.renameFile(fileHeader, "new-file-name.pdf");
或者
new ZipFile("filename.zip").renameFile("entry-to-be-changed.pdf", "new-file-name.pdf");
或者
Map<String, String> fileNamesMap = new HashMap<>();
fileNamesMap.put("firstFile.txt", "newFileFirst.txt");
fileNamesMap.put("secondFile.pdf", "newSecondFile.pdf");
fileNamesMap.put("some-folder/thirdFile.bin", "some-folder/newThirdFile.bin");
new ZipFile("filename.zip").renameFiles(fileNamesMap);
或者//文件夹
new ZipFile("filename.zip").renameFile("some-folder/some-sub-folder/some-entry.pdf", "some-folder/some-sub-folder/new-entry.pdf");
//合并zip文件
new ZipFile("split_zip_file.zip").mergeSplitFiles(new File("merged_zip_file.zip"));
//遍历zip文件
List<FileHeader> fileHeaders = new ZipFile("zipfile.zip").getFileHeaders();
fileHeaders.stream().forEach(fileHeader -> System.out.println(fileHeader.getFileName()));
//判断zip文件的信息
new ZipFile("encrypted_zip_file.zip").isEncrypted();
new ZipFile("split_zip_file.zip").isSplitArchive();
new ZipFile("valid_zip_file.zip").isValidZipFile();
//zip文件注释
new ZipFile("some_zip_file.zip").setComment("Some comment");
new ZipFile("some_zip_file.zip").setComment("");
new ZipFile("some_zip_file.zip").getComment();
使用流进行压缩和解压
import net.lingala.zip4j.io.outputstream.ZipOutputStream;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class ZipOutputStreamExample {
public void zipOutputStreamExample(File outputZipFile, List<File> filesToAdd, char[] password,
CompressionMethod compressionMethod, boolean encrypt,
EncryptionMethod encryptionMethod, AesKeyStrength aesKeyStrength)
throws IOException {
ZipParameters zipParameters = buildZipParameters(compressionMethod, encrypt, encryptionMethod, aesKeyStrength);
byte[] buff = new byte[4096];
int readLen;
try(ZipOutputStream zos = initializeZipOutputStream(outputZipFile, encrypt, password)) {
for (File fileToAdd : filesToAdd) {
// Entry size has to be set if you want to add entries of STORE compression method (no compression)
// This is not required for deflate compression
if (zipParameters.getCompressionMethod() == CompressionMethod.STORE) {
zipParameters.setEntrySize(fileToAdd.length());
}
zipParameters.setFileNameInZip(fileToAdd.getName());
zos.putNextEntry(zipParameters);
try(InputStream inputStream = new FileInputStream(fileToAdd)) {
while ((readLen = inputStream.read(buff)) != -1) {
zos.write(buff, 0, readLen);
}
}
zos.closeEntry();
}
}
}
private ZipOutputStream initializeZipOutputStream(File outputZipFile, boolean encrypt, char[] password)
throws IOException {
FileOutputStream fos = new FileOutputStream(outputZipFile);
if (encrypt) {
return new ZipOutputStream(fos, password);
}
return new ZipOutputStream(fos);
}
private ZipParameters buildZipParameters(CompressionMethod compressionMethod, boolean encrypt,
EncryptionMethod encryptionMethod, AesKeyStrength aesKeyStrength) {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setCompressionMethod(compressionMethod);
zipParameters.setEncryptionMethod(encryptionMethod);
zipParameters.setAesKeyStrength(aesKeyStrength);
zipParameters.setEncryptFiles(encrypt);
return zipParameters;
}
}
import net.lingala.zip4j.io.inputstream.ZipInputStream;
import net.lingala.zip4j.model.LocalFileHeader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class ZipInputStreamExample {
public void extractWithZipInputStream(File zipFile, char[] password) throws IOException {
LocalFileHeader localFileHeader;
int readLen;
byte[] readBuffer = new byte[4096];
InputStream inputStream = new FileInputStream(zipFile);
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream, password)) {
while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
File extractedFile = new File(localFileHeader.getFileName());
try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
while ((readLen = zipInputStream.read(readBuffer)) != -1) {
outputStream.write(readBuffer, 0, readLen);
}
}
}
}
}
}
进度监控
ZipFile zipFile = new ZipFile(generatedZipFile, PASSWORD);
ProgressMonitor progressMonitor = zipFile.getProgressMonitor();
zipFile.setRunInThread(true); //必须有这行代码,开启一个后台线程
zipFile.addFolder(new File("/some/folder"));
while (!progressMonitor.getState().equals(ProgressMonitor.State.READY)) {
System.out.println("Percentage done: " + progressMonitor.getPercentDone());
System.out.println("Current file: " + progressMonitor.getFileName());
System.out.println("Current task: " + progressMonitor.getCurrentTask());
Thread.sleep(100);
}
if (progressMonitor.getResult().equals(ProgressMonitor.Result.SUCCESS)) {
System.out.println("Successfully added folder to zip");
} else if (progressMonitor.getResult().equals(ProgressMonitor.Result.ERROR)) {
System.out.println("Error occurred. Error message: " + progressMonitor.getException().getMessage());
} else if (progressMonitor.getResult().equals(ProgressMonitor.Result.CANCELLED)) {
System.out.println("Task cancelled");
}