需求:壓縮目標(biāo)文件夾,保持目錄結(jié)構(gòu)不變,生成一個(gè)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();
}
}
}
運(yùn)行:
目錄結(jié)構(gòu):

image.png
壓縮包目錄結(jié)構(gòu):

image.png
分析:
1.優(yōu)點(diǎn)
直接運(yùn)行是沒(méi)有問(wèn)題的,addDirectoryToZip這個(gè)方法,碰到文件夾就遞歸,碰到文件就進(jìn)行寫(xiě)操作。代碼還比較簡(jiǎn)潔。
2.不足
- 缺少為空的處理
例如空文件夾C,方法會(huì)忽略掉 - 缺少異常情況考慮
例如傳入zipFilePath上級(jí)的目錄不存在,會(huì)報(bào)錯(cuò)
3.改進(jìn)
/**
* 確保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) {
// 拋業(yè)務(wù)異常
}
}
}
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();
}
}