public File compress(String resource, File resourceFile, FileFilter filter, JSONArray subFileMd5List) throws Exception {
java.util.zip.ZipOutputStream zos = null;
try {
String prefix = resource.replaceAll("\\\\", "_");
prefix = prefix.replaceAll("/", "_");
while (prefix.length() < 3)
prefix += "_";
File file = File.createTempFile(prefix, ".zip");
logger.info("压缩{}->{}", resource, file);
FileOutputStream out = new FileOutputStream(file);
zos = new ZipOutputStream(out);
compress(resourceFile, zos, resourceFile.getName(), true, filter, subFileMd5List);
return file;
} finally {
if (zos != null) {
try {
zos.close();
} catch (IOException e) {
}
}
}
}
private void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure, FileFilter filter, JSONArray subFileMd5List) throws Exception {
byte[] buf = new byte[4096];
if (filter != null && !filter.accept(sourceFile)) {
return;
}
if (sourceFile.isFile()) {
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
ZipEntry entry = new ZipEntry(name);
entry.setTime(sourceFile.lastModified());
zos.putNextEntry(entry);
// copy文件到zip输出流中
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
// Complete the entry
zos.closeEntry();
in.close();
JSONObject obj = new JSONObject();
obj.put("url", name);
obj.put("md5", FileUtil.getFileMD5String(sourceFile));
subFileMd5List.add(obj);
} else {
File[] listFiles = sourceFile.listFiles();
java.util.Arrays.sort(listFiles);
if (listFiles == null || listFiles.length == 0) {
// 需要保留原来的文件结构时,需要对空文件夹进行处理
if (KeepDirStructure) {
// 空文件夹的处理
ZipEntry entry = new ZipEntry(name + "/");
entry.setTime(sourceFile.lastModified());
zos.putNextEntry(entry);
// 没有文件,不需要文件的copy
zos.closeEntry();
}
} else {
for (File file : listFiles) { // 判断是否需要保留原来的文件结构
if (KeepDirStructure) {
// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
compress(file, zos, name + "/" + file.getName(), KeepDirStructure, filter, subFileMd5List);
} else {
compress(file, zos, file.getName(), KeepDirStructure, filter, subFileMd5List);
}
}
}
}
}
public void decompress(File srcFile, String destDirPath, FileFilter filter) throws Exception {
try (java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(srcFile)) {
Enumeration<?> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
// 如果是文件夹,就创建个文件夹
if (entry.isDirectory()) {
String dirPath = destDirPath + "/" + entry.getName();
File dir = new File(dirPath);
if (filter == null || filter.accept(dir)) {
dir.mkdirs();
dir.setLastModified(entry.getTime());
}
} else {
// 如果是文件,就先创建一个文件,然后用io流把内容copy过去
File targetFile = new File(destDirPath + "/" + entry.getName());
if (filter == null || filter.accept(targetFile)) {
// 保证这个文件的父文件夹必须要存在
if (!targetFile.getParentFile().exists()) {
targetFile.getParentFile().mkdirs();
}
targetFile.createNewFile();
// 将压缩文件内容写入到这个文件中
try (java.io.InputStream is = zipFile.getInputStream(entry); FileOutputStream fos = new FileOutputStream(targetFile);) {
int len;
byte[] buf = new byte[BUFFER_SIZE];
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
}
targetFile.setLastModified(entry.getTime());
}
}
}
}
}