公司分给了我一个难搞的需求,需要处理ZIP的相关操作,在处理需求时遇到各种问题,大家仅供参考,可以避坑,遇到其他问题可以评论区留言
1.解压ZIP压缩文件
/**
*
* @autor wangsz
* @param zipFilePath zip文件路径
* @param destDirectory zip文件解压到哪里
* @param charset 指定字符编码
* @return
* @throws IOException
*/
public static boolean unzip(String zipFilePath, String destDirectory, Charset charset) throws IOException {
File destDir = new File(destDirectory);
if (!destDir.exists()) {
destDir.mkdirs();
}
try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath), charset)) {
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
String filePath = destDirectory + File.separator + entry.getName();
if (!entry.isDirectory()) {
extractFile(zipIn, filePath);
} else {
File dir = new File(filePath);
dir.mkdirs();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
}
return true;
}
private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
bos.close();
}
2.压缩zip文件
/**
* 压缩文件夹到zip
* @param sourceDirectory 文件夹路径
* @param zipFilePath zip的位置
* @param charset 指定字符编码
* @throws IOException
*/
public static void zip(String sourceDirectory, String zipFilePath, Charset charset) throws IOException {
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath), charset)) {
File fileToZip = new File(sourceDirectory);
zipFile(fileToZip, fileToZip.getName(), zipOut);
}
}
private static void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException {
if (fileToZip.isHidden()) {
return;
}
if (fileToZip.isDirectory()) {
if (fileName.endsWith("/")) {
zipOut.putNextEntry(new ZipEntry(fileName));
zipOut.closeEntry();
} else {
zipOut.putNextEntry(new ZipEntry(fileName + "/"));
zipOut.closeEntry();
}
File[] children = fileToZip.listFiles();
for (File childFile : children) {
zipFile(childFile, fileName + "/" + childFile.getName(), zipOut);
}
return;
}
FileInputStream fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileName);
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[BUFFER_SIZE];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
}
3. 解压包含中文的压缩包,需将字符编码指定成GBK,实测utf-8不好用
Charset charset = Charset.forName("GBK"); // 使用指定的字符编码(例如GBK)
4.压缩文件为zip后,写入输出流供前端下载
/**
* 压缩文件夹到zip
* @param sourceDirectory 文件夹路径
* @param charset 指定字符编码
* @throws IOException
*/
public static void zip(String sourceDirectory, Charset charset, HttpServletResponse response) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zipOut = new ZipOutputStream(baos, charset)) {
File fileToZip = new File(sourceDirectory);
zipFile(fileToZip, fileToZip.getName(), zipOut);
}
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=\"compressed.zip\"");
try (OutputStream os = response.getOutputStream()) {
os.write(baos.toByteArray());
os.flush();
}
}