compress file or direcotry, but it can ignore the empty directory.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @author: piumnl
* @since: 2016-12-20
*/
public class ZipCompress {
/**
* 压缩文件
* @param srcFile 源文件/夹
* @param destFile 生成的目标文件
*/
public static void compressDirectory(File srcFile, File destFile) {
validate(srcFile, destFile);
if (destFile.isDirectory()) {
destFile = new File(destFile.getAbsolutePath() + ".zip");
}
try (FileOutputStream output = new FileOutputStream(destFile);
CheckedOutputStream checked = new CheckedOutputStream(output, new CRC32());
ZipOutputStream zipOutputStream = new ZipOutputStream(checked)) {
compressDirectory(zipOutputStream, srcFile, "");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 递归压缩
* @param zipOutputStream 压缩的输出流
* @param src 要压缩的目录,此处如果是空目录会被忽略掉
* @param pre 前缀,重要!!!通过它分级
* @throws IOException .
*/
private static void compressDirectory(ZipOutputStream zipOutputStream, File src, String pre)
throws IOException {
File[] files = src.listFiles();
for (File file : files != null ? files : new File[0]) {
if (file.isDirectory()) {
compressDirectory(zipOutputStream, file, pre + file.getName() + "/");
} else {
compressZipEntry(zipOutputStream, file, pre);
}
}
}
/**
* 整理 生成 fileInputStream 对象并调用 compressZipEntry。
* @param zipOutputStream 压缩的输出流
* @param file 要压缩的文件
* @param pre 前缀,重要!!!通过它分级
*/
private static void compressZipEntry(ZipOutputStream zipOutputStream, File file, String pre) {
try (FileInputStream fileInputStream = new FileInputStream(file)) {
compressZipEntry(zipOutputStream, fileInputStream, pre + file.getName());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 压缩单个文件
* @param srcFile 要压缩的文件
* @param destFile 压缩后存放的文件
*/
public static void compressFile(File srcFile, File destFile) {
validate(srcFile, destFile);
if (destFile.isDirectory()) {
destFile = new File(destFile.getAbsolutePath() + ".zip");
}
try (FileInputStream input = new FileInputStream(srcFile);
FileOutputStream output = new FileOutputStream(destFile);
CheckedOutputStream checked = new CheckedOutputStream(output, new CRC32());
ZipOutputStream zipOutputStream = new ZipOutputStream(checked)){
compressZipEntry(zipOutputStream, input, srcFile.getName());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 底层压缩
* @param output 压缩的输出流
* @param input 要压缩的文件流
* @param entryName 文件存放在zip中的名字
*/
private static void compressZipEntry(ZipOutputStream output, FileInputStream input, String entryName) {
try {
ZipEntry entry = new ZipEntry(entryName);
output.putNextEntry(entry);
byte[] data = new byte[1024];
int read;
while ((read = input.read(data, 0, data.length)) != -1) {
output.write(data, 0, read);
}
output.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 验证文件的正确性。
* @param srcFile 要压缩的文件
* @param destFile 生成的目标文件
*/
private static void validate(File srcFile, File destFile) {
if (srcFile == null || destFile == null) {
throw new NullPointerException();
}
if (destFile.getParentFile().getAbsolutePath().contains(srcFile.getAbsolutePath())) {
throw new IllegalArgumentException("src can't contain the dest.");
}
}
}