需求:压缩目标文件夹,保持目录结构不变,生成一个zip
回答:智能给出的代码
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipDirectory {
public static void main(String[] args) {
String sourceFolder = "源文件夹路径";
String zipFilePath = "压缩文件路径";
zipDirectory(sourceFolder, zipFilePath);
}
private static void zipDirectory(String sourceFolder, String zipFilePath) {
try {
FileOutputStream fos = new FileOutputStream(zipFilePath);
ZipOutputStream zos = new ZipOutputStream(fos);
File sourceFile = new File(sourceFolder);
addDirectoryToZip(zos, sourceFile, "");
zos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void addDirectoryToZip(ZipOutputStream zos, File sourceFile, String parentDirectoryName) throws IOException {
File[] files = sourceFile.listFiles();
byte[] buffer = new byte[1024];
int bytesRead;
for (File file : files) {
if (file.isDirectory()) {
String directoryName = file.getName();
addDirectoryToZip(zos, file, parentDirectoryName + "/" + directoryName);
continue;
}
FileInputStream fis = new FileInputStream(file);
String entryName = parentDirectoryName + "/" + file.getName();
ZipEntry zipEntry = new ZipEntry(entryName);
zos.putNextEntry(zipEntry);
while ((bytesRead = fis.read(buffer)) != -1) {
zos.write(buffer, 0, bytesRead);
}
fis.close();
zos.closeEntry();
}
}
}
运行:
目录结构:

image.png
压缩包目录结构:

image.png
分析:
1.优点
直接运行是没有问题的,addDirectoryToZip这个方法,碰到文件夹就递归,碰到文件就进行写操作。代码还比较简洁。
2.不足
- 缺少为空的处理
例如空文件夹C,方法会忽略掉 - 缺少异常情况考虑
例如传入zipFilePath上级的目录不存在,会报错
3.改进
/**
* 确保path路径文件存在
* @param absolutePath 文件或者目录的全路径
* @param directoryFlag 是否是目录
*/
public static void makeSurePathExist(String absolutePath, Boolean directoryFlag) {
File file = new File(absolutePath);
if (!file.exists()) {
if (directoryFlag) {
file.mkdirs();
return;
}
File parentDir = file.getParentFile();
if (!parentDir.exists()) {
parentDir.mkdirs();
}
try {
file.createNewFile();
} catch (Exception e) {
// 抛业务异常
}
}
}
private static void zipDirectory(String sourceFolder, String zipFilePath) {
// 保证zipFilePath存在
makeSurePathExist(zipFilePath);
try(ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
addDirectoryToZip(zos, new File(sourceFolder), "");
} catch (Exception e) {
e.printStackTrace();
}
}
private static void addDirectoryToZip(ZipOutputStream zos, File sourceFile, String parentDirectoryName) throws IOException {
File[] files = sourceFile.listFiles();
byte[] buffer = new byte[1024];
int bytesRead;
// 处理文件夹为空情况
if (files.length == 0) {
zos.putNextEntry(new ZipEntry(parentDirectoryName + "/"));
}
for (File file : files) {
if (file.isDirectory()) {
String directoryName = file.getName();
addDirectoryToZip(zos, file, parentDirectoryName + "/" + directoryName);
continue;
}
FileInputStream fis = new FileInputStream(file);
String entryName = parentDirectoryName + "/" + file.getName();
ZipEntry zipEntry = new ZipEntry(entryName);
zos.putNextEntry(zipEntry);
while ((bytesRead = fis.read(buffer)) != -1) {
zos.write(buffer, 0, bytesRead);
}
fis.close();
zos.closeEntry();
}
}